Подзапрос T-SQL Max (дата) и соединения
Я пытаюсь объединить несколько таблиц, но одна из таблиц имеет несколько записей для partid с разными датами. Я хочу получить запись с последней датой.
вот некоторые примеры таблиц:
Table: MyParts
Partid Partnumber Description
1 ABC-123 Pipe
2 ABC-124 Handle
3 ABC-125 Light
Table: MyPrices
Partid Price PriceDate
1 1/1/2005
1 1/1/2007
1 1/1/2009
2 1/1/2005
2 1/1/2006
2 1/1/2008
3 1/1/2008
3 1/1/2009
если бы я просто хотел найти самую последнюю цену за определенную часть, я мог бы сделать:
SELECT * FROM MyPrice WHERE PriceDate = (SELECT MAX(PriceDate)
FROM MyPrice WHERE Partid = 1)
однако я хочу сначала сделать соединение и вернуть правильную цену для всех частей, а не только для одной. Это то, что я попробовал:
SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE
MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice)
результаты неверны, так как он принимает самую высокую дату цены всей таблицы.
SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE
MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice WHERE MyPrice.Partid =
MyParts.Partid)
это ошибки.
что я могу сделать, чтобы получить результаты, я хочу.
10 ответов
попробуйте это:
Select *,
Price = (Select top 1 Price
From MyPrices
where PartID = mp.PartID
order by PriceDate desc
)
from MyParts mp
вот еще один способ сделать это без подзапросов. Этот метод часто превосходят другие, поэтому стоит протестировать оба метода, чтобы увидеть, что дает лучшую производительность.
SELECT
PRT.PartID,
PRT.PartNumber,
PRT.Description,
PRC1.Price,
PRC1.PriceDate
FROM
MyParts PRT
LEFT OUTER JOIN MyPrices PRC1 ON
PRC1.PartID = PRT.PartID
LEFT OUTER JOIN MyPrices PRC2 ON
PRC2.PartID = PRC1.PartID AND
PRC2.PriceDate > PRC1.PriceDate
WHERE
PRC2.PartID IS NULL
Это даст несколько результатов, если у вас есть две цены с одинаковым точным PriceDate (большинство других решений будет делать то же самое). Кроме того, мне нечего учитывать, что последняя дата цены находится в будущем. Вы можете рассмотреть возможность проверки этого независимо от того, какой метод вы закончите с помощью.
попробуйте присоединиться к подзапросу MyPrice
для получения MAX(PriceDate)
:
SELECT a.*, MyPriceDate.Price, MyPriceDate.PriceDate
FROM MyParts a
INNER JOIN (
SELECT Partid, MAX(PriceDate) AS MaxPriceDate
FROM MyPrice
GROUP BY Partid
) dt ON a.Partid = dt.Partid
INNER JOIN MyPrice ON dt.Partid = MyPrice.Partid
AND a.PriceDate = dt.MaxPriceDate
на 2005 используйте ROW_NUMBER()
:
SELECT * FROM
( SELECT p.*,
ROW_NUMBER() OVER(PARTITION BY Partid ORDER BY PriceDate DESC) AS rn
FROM MyPrice AS p ) AS t
WHERE rn=1
что-то вроде этого
SELECT *
FROM MyParts
LEFT JOIN
(
SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID
) myprice
ON MyParts.Partid = MyPrice.Partid
Если вы знаете свой partid или можете ограничить его, поместите его в соединение.
SELECT myprice.partid, myprice.partdate, myprice2.Price, *
FROM MyParts
LEFT JOIN
(
SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID
) myprice
ON MyParts.Partid = MyPrice.Partid
Inner Join MyPrice myprice2
on myprice2.pricedate = myprice.pricedate
and myprice2.partid = myprice.partid
SELECT
*
FROM
(SELECT MAX(PriceDate) AS MaxP, Partid FROM MyPrices GROUP BY Partid) MaxP
JOIN
MyPrices MP On MaxP.Partid = MP.Partid AND MaxP.MaxP = MP.PriceDate
JOIN
MyParts P ON MP.Partid = P.Partid
сначала вы получите последний pricedate для partid (стандартный агрегат), затем присоединитесь к нему, чтобы получить цены (которые не могут быть в агрегате), а затем получите детали детали.
регистрация в таблице цены, а затем выберите запись за последний день:
select pa.partid, pa.Partnumber, max(pr.price)
from myparts pa
inner join myprices pr on pr.partid = pa.partid
where pr.PriceDate = (
select max(PriceDate)
from myprices
where partid = pa.partid
)
max () в случае, если есть несколько цен в день; я предполагаю, что вы хотели бы отобразить самый высокий. Если ваша таблица цен имеет столбец id, вы можете избежать max () и упростить, например:
select pa.partid, pa.Partnumber, pr.price
from myparts pa
inner join myprices pr on pr.partid = pa.partid
where pr.priceid = (
select max(priceid)
from myprices
where partid = pa.partid
)
П. С. Использование УМК в!все остальные ответы должны работать, но используя тот же синтаксис (и понимая, почему ошибка)
SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE
MyPart.PriceDate = (SELECT MAX(MyPrice2.PriceDate) FROM MyPrice as MyPrice2
WHERE MyPrice2.Partid = MyParts.Partid)
попробуйте следующий пример кода:
select t1.*, t2.partprice, t2.partdate
from myparts t1
join myprices t2
on t1.partid = t2.partid
where partdate =
(select max(partdate) from myprices t3
where t3.partid = t2.partid group by partid)
для MySQL, пожалуйста, найдите следующий запрос:
select * from (select PartID, max(Pricedate) max_pricedate from MyPrices group bu partid) as a
inner join MyParts b on
(a.partid = b.partid and a.max_pricedate = b.pricedate)
внутри подзапроса он получает max pricedate для каждого partyid MyPrices тогда, внутреннее соединение с MyParts с помощью partid и max_pricedate