我有一张桌子,上面有产品库存。问题在于,每次库存变化时,都会存储新值以及新数量。示例:
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)
)
由于查询速度很慢,应该将其加入另一个查询中,所以我真的很想输入一些有关如何更好地做到这一点的信息。
还有其他方法吗?
答案 0 :(得分:5)
使用分析功能。在这种情况下可以使用row_number
。
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
或使用first_value
。
SELECT DISTINCT ProductID, FIRST_VALUE(Quantity) OVER(partition by ProductID order by LstUpdte desc) as quantuity
FROM Stock
答案 1 :(得分:3)
另一种选择是将WITH TIES
与Row_Number()
配合使用
全面披露: 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
答案 2 :(得分: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
答案 3 :(得分:1)
因此您可以使用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加入所需的任何表中。