Sql 获取按ID分组的最新条目

Sql 获取按ID分组的最新条目,sql,sql-server,max,Sql,Sql Server,Max,我有一张有存货的桌子。问题是,每次库存发生变化时,新值都会与新数量一起存储。例如: ProductID | Quantity | LastUpdate 1 123 2019.01.01 2 234 2019.01.01 1 444 2019.01.02 2 222 2019.01.02 因此,我需要获得每种产品的最新库存更新,并返回以下信息: ProductI

我有一张有存货的桌子。问题是,每次库存发生变化时,新值都会与新数量一起存储。例如:

ProductID | Quantity | LastUpdate
1           123        2019.01.01
2           234        2019.01.01
1           444        2019.01.02
2           222        2019.01.02
因此,我需要获得每种产品的最新库存更新,并返回以下信息:

ProductID | Quantity
1           444
2           222     
下面的SQL可以工作,但速度很慢

SELECT ProductID, Quantity
FROM (
    SELECT ProductID, Quantity
    FROM Stock
    WHERE LastUpdate 
    IN (SELECT MAX(LastUpdate) FROM Stock GROUP BY ProductID)
) 
由于查询速度很慢,并且应该与另一个查询保持连接,因此我真的需要一些关于如何更好地执行此操作的信息

还有其他方法吗?

使用分析函数。在这种情况下可以使用

SELECT ProductID, Quantity
FROM (SELECT ProductID, Quantity, row_number() over(partition by ProductID order by LstUpdte desc) as rnum
      FROM Stock
     ) s
WHERE RNUM = 1
或与

row_number()函数可能是最有效的,但是查询中最大的问题是在子查询中使用in语句,这有点棘手,但是连接速度更快。这个查询应该会得到您想要的结果,并且速度会快得多

SELECT 
     a.ProductID
    ,a.Quantity 
FROM stock as a 
INNER JOIN (
            SELECT 
                 ProductID
                ,MAX(LastUpdate) as LastUpdate
            FROM stock 
            GROUP BY ProductID  
            ) b 
ON  a.ProductID = b.ProductId AND 
    a.LastUpdate = b.LastUpdate
因此可以使用CTE(公共表表达式)

基础数据:

SELECT  1 AS ProductID
       ,123 AS Quantity
       ,'2019-01-01' as LastUpdate
INTO #table
UNION 
SELECT  2 AS ProductID
       ,234 AS Quantity
       ,'2019-01-01' as LastUpdate
UNION
SELECT  1 AS ProductID
       ,444 AS Quantity
       ,'2019-01-02' as LastUpdate
UNION
SELECT  2 AS ProductID
       ,222 AS Quantity
       ,'2019-01-02' as LastUpdate
下面是使用公共表表达式的代码

WITH CTE (ProductID, Quantity, LastUpdate, Rnk)
AS
 (
 SELECT  ProductID
        ,Quantity
        ,LastUpdate
        ,ROW_NUMBER() OVER(PARTITION BY ProductID ORDER BY LastUpdate DESC) AS Rnk
 FROM #table
 )
SELECT ProductID, Quantity, LastUpdate
FROM CTE
WHERE rnk = 1
返回


然后,您可以将CTE加入到您需要的任何表中。

另一个选项是使用带领带的
行号()配合使用

全面披露:Vamsi的回答将是一个更有效的推动

示例

Select Top 1 with ties * 
 From  YourTable
 Order by Row_Number() over (Partition By ProductID Order by LastUpdate Desc)
返回

ProductID   Quantity    LastUpdate
1           444         2019-01-02
2           222         2019-01-02

您是否意识到您的查询与您的描述不符?它不等同于答案中提供的解决方案。@RadimBača请详细说明,如果缺少示例数据的第二行,则查询将返回三行而不是两行。
ProductID   Quantity    LastUpdate
1           444         2019-01-02
2           222         2019-01-02