首页 > 解决方案 > 选择值为最大值的行,并且一列为空

问题描述

我有一张桌子,products看起来像这样:

productID | version | done  
1         | 1       | 2000-01-01  
1         | 2       | NULL  
2         | 1       | NULL  
2         | 2       | 2000-01-01  

假定版本在增加。

我想要的是一个返回 ProductID 及其最高/当前版本的查询,如果该版本的 Done 列为 NULL。简而言之,我想要所有最新版本未完成的产品,以及相应的版本。目标:在产品中,找到尚未“完成”/处理的具有新版本的产品。

注意:在上面的示例中,我希望查询仅返回 ProductID 1,版本 2。我不想要一个产品的最高未完成版本,我想要一个产品的最高版本,如果它没有完成的话。对不起,如果澄清是多余的。

我写了一个查询,似乎可以满足我的要求:

SELECT productID ProductID, version Version 
FROM products
WHERE done IS NULL
AND version IN (
    SELECT MAX(version)
    FROM products
    GROUP BY productID 
)

但是,它似乎也不是很有效。所以我的问题是,有没有更好的方法来处理这个查询?

标签: sql-servertsql

解决方案


我们可以ROW_NUMBER在这里尝试使用:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY productID ORDER BY version DESC) rn
    FROM products
)

SELECT productID, version
FROM cte
WHERE rn = 1 AND done IS NULL;

演示

上面的 CTE 根据版本为每个产品的最新记录分配一个行号,从 1 开始。然后,我们子查询并仅保留最新的产品记录恰好没有分配给done列的值。


推荐阅读