Подзапрос T-SQL Макс (Дата) и Соединения - PullRequest
27 голосов
/ 18 мая 2009

Я пытаюсь объединить несколько таблиц, но в одной из таблиц есть несколько записей для партии с разными датами. Я хочу получить запись с самой последней датой.

Вот несколько примеров таблиц:

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/1/2005
1        $2           1/1/2007
1        $3           1/1/2009
2        $2           1/1/2005
2        $4           1/1/2006
2        $5           1/1/2008
3        $10          1/1/2008
3        $12          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 ]

31 голосов
/ 18 мая 2009

Попробуйте это:

Select *,
    Price = (Select top 1 Price 
             From MyPrices 
             where PartID = mp.PartID 
             order by PriceDate desc
            )
from MyParts mp
31 голосов
/ 18 мая 2009

Вот еще один способ сделать это без подзапросов. Этот метод часто превосходит другие, поэтому стоит протестировать оба метода, чтобы увидеть, какой из них дает наилучшую производительность.

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

Это даст несколько результатов, если у вас есть две цены с одинаковой EXACT PriceDate (большинство других решений будут делать то же самое). Кроме того, мне не за что отвечать за дату последней цены в будущем. Вы можете рассмотреть возможность проверки этого независимо от того, какой метод вы используете.

10 голосов
/ 18 мая 2009

Попробуйте присоединиться к подзапросу 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
5 голосов
/ 19 мая 2009

В 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
4 голосов
/ 18 мая 2009

как то так

SELECT * 
FROM MyParts 
LEFT JOIN 
(
SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID
) myprice
 ON MyParts.Partid = MyPrice.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
2 голосов
/ 18 мая 2009

Присоединитесь к таблице цен, а затем выберите запись за последний день:

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 () и упростить, например:

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
)

P.S. Вместо этого используйте решение wcm!

2 голосов
/ 18 мая 2009
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

Сначала вы получите последнюю цену для partid (стандартная совокупность), затем присоединитесь к ней, чтобы получить цены (которых не может быть в совокупности), а затем получите детали детали.

1 голос
/ 18 мая 2009

Все остальные ответы должны работать, но с использованием того же синтаксиса (и понимания, почему ошибка)

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)
0 голосов
/ 25 июня 2018

Для 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)

Внутри подзапроса он получает максимальную цену для каждой партии MyPrices, внутреннее соединение с MyParts с использованием partid и max_pricedate

0 голосов
/ 08 ноября 2017

Пожалуйста, попробуйте следующий пример кода:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...