T-SQL子查询最大(日期)和联接

Max*_*eek 27 sql t-sql sql-server join subquery

我正在尝试连接多个表,但其中一个表有一个具有不同日期的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/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
Run Code Online (Sandbox Code Playgroud)

如果我只是想找到某个部分的最新价格,我可以做:

SELECT * FROM MyPrice WHERE PriceDate = (SELECT MAX(PriceDate) 
FROM MyPrice WHERE Partid = 1)
Run Code Online (Sandbox Code Playgroud)

但是我想首先加入,然后为所有部分而不是一个部分找回正确的价格.这是我尝试过的:

SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE 
MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice)
Run Code Online (Sandbox Code Playgroud)

结果是错误的,因为它需要整个表的最高价格日期.

SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE 
MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice WHERE MyPrice.Partid =   
MyParts.Partid)
Run Code Online (Sandbox Code Playgroud)

那错误了.

我该怎么做才能得到我想要的结果.

wcm*_*wcm 33

试试这个:

Select *,
    Price = (Select top 1 Price 
             From MyPrices 
             where PartID = mp.PartID 
             order by PriceDate desc
            )
from MyParts mp
Run Code Online (Sandbox Code Playgroud)

  • 根据MyParts中的行数,这是一个子查询,从MyParts表返回的每一行都必须评估一次子查询.与使用游标相比,这可能会非常昂贵. (3认同)
  • 我喜欢Tom H的回答.它有一定的简约优雅.这只是表明你不应该只是敲出弹出的第一段SQL. (3认同)

Tom*_*m H 33

这是在没有子查询的情况下执行此操作的另一种方法.这种方法通常会优于其他方法,因此值得测试两种方法,以确定哪种方法能够提供最佳性能.

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
Run Code Online (Sandbox Code Playgroud)

如果您有两个具有相同EXACT PriceDate的价格,则会产生多个结果(大多数其他解决方案将执行相同的操作).另外,我没有什么可以解释将来的最后价格日期.无论您最终使用哪种方法,都可能需要考虑检查.


KM.*_*KM. 11

尝试加入子查询__CODE__以便检索__CODE__:

SELECT
    MyParts.*,MyPriceDate.Price,MyPriceDate.PriceDate
    FROM MyParts
        INNER JOIN (SELECT Partid, MAX(PriceDate) AS MaxPriceDate FROM MyPrice GROUP BY Partid) dt ON MyParts.Partid = dt.Partid
        INNER JOIN MyPrice ON dt.Partid = MyPrice.Partid AND MyPrice.PriceDate=dt.MaxPriceDate
Run Code Online (Sandbox Code Playgroud)


A-K*_*A-K 6

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
Run Code Online (Sandbox Code Playgroud)


u07*_*7ch 5

像这样

SELECT * 
FROM MyParts 
LEFT JOIN 
(
SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID
) myprice
 ON MyParts.Partid = MyPrice.Partid 
Run Code Online (Sandbox Code Playgroud)

如果您知道自己的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
Run Code Online (Sandbox Code Playgroud)