我有这个表如下所示...如何根据changeno仅选择id的最新数据?
+----+--------------+------------+--------+
| id | data | changeno | |
+----+--------------+------------+--------+
| 1 | Yes | 1 | |
| 2 | Yes | 2 | |
| 2 | Maybe | 3 | |
| 3 | Yes | 4 | |
| 3 | Yes | 5 | |
| 3 | No | 6 | |
| 4 | No | 7 | |
| 5 | Maybe | 8 | |
| 5 | Yes | 9 | |
+----+---------+------------+-------------+
我想要这个结果......
+----+--------------+------------+--------+
| id | data | changeno | |
+----+--------------+------------+--------+
| 1 | Yes | 1 | |
| 2 | Maybe | 3 | |
| 3 | No | 6 | |
| 4 | No | 7 | |
| 5 | Yes | 9 | |
+----+---------+------------+-------------+
我目前有这个SQL语句......
SELECT id,data,MAX(changeno)as changeno FROM Table1 GROUP BY id;
显然它不会返回我想要的东西。由于aggrerate函数,这应该返回错误。如果我在GROUP BY子句下添加字段,它可以工作,但它不会返回我想要的内容。到目前为止,SQL语句是我能想到的最接近的语句。如果有人能帮助我,我会很感激。提前谢谢你:)
答案 0 :(得分:7)
这通常被称为"greatest-n-per-group"问题。在SQL Server 2005及更高版本中解决此问题的一种方法是使用基于ROW_NUMBER()
列分组的计算id
的CTE,并首先按最大changeno
排序: / p>
;WITH cte AS
(
SELECT id, data, changeno,
rn = ROW_NUMBER() OVER (PARTITION BY id ORDER BY changeno DESC)
FROM dbo.Table1
)
SELECT id, data, changeno
FROM cte
WHERE rn = 1
ORDER BY id;
答案 1 :(得分:4)
您想使用row_number()
:
select id, data, changeno
from (SELECT t.*,
row_number() over (partition by id order by changeno desc) as seqnum
FROM Table1 t
) t
where seqnum = 1;
答案 2 :(得分:0)
不是格式良好或性能优化的查询,但对于小任务,它可以正常工作。
SELECT * FROM TEST WHERE changeno IN(SELECT MAX(changeno) 从测试 GROUP BY id)
答案 3 :(得分:0)
用于其他替代方案:
DECLARE @Table1 TABLE
(
id INT, data VARCHAR(5), changeno INT
);
INSERT INTO @Table1
SELECT 1,'Yes',1
UNION ALL
SELECT 2,'Yes',2
UNION ALL
SELECT 2,'Maybe',3
UNION ALL
SELECT 3,'Yes',4
UNION ALL
SELECT 3,'Yes',5
UNION ALL
SELECT 3,'No',6
UNION ALL
SELECT 4,'No',7
UNION ALL
SELECT 5,'Maybe',8
UNION ALL
SELECT 5,'Yes',9
SELECT Y.id, Y.data, Y.changeno
FROM @Table1 Y
INNER JOIN (
SELECT id, changeno = MAX(changeno)
FROM @Table1
GROUP BY id
) X ON X.id = Y.id
WHERE X.changeno = Y.changeno
ORDER BY Y.id