我不知道如何概括地解释这一点,所以请允许我举一个例子。
SELECT ParentId, Id, Number
FROM SomeTable
ORDER BY ParentId, Id
给出
ParentId Id Number
2997 1145445 400
2997 1145449 400
2997 1145577 400
2997 1146518 405
2999 1145470 400
2999 1145502 400
2999 1145504 400
3016 1145633 400
3016 1145636 400
3016 1145677 400
3016 1145686 405
3037 1145885 400
3037 1145906 405
3037 1145922 400
3037 1145925 400
3162 1147324 400
3162 1147327 400
3162 1147329 400
3162 1147332 400
3162 1147334 405
3162 1147339 400
3162 1147341 405
3162 1147345 406
3162 1147347 410
(这只是真实数据的子集,但足以解释问题)。
问题:
查询(尽可能优雅和高效,最好没有子查询、游标等),精确选择 Number = 400
的所有行,但添加以下列:
Id_405
:Number = 405
的行的 Id
,并且在该 400 和 400 之间具有相同的 ParentId
接下来的 400 个,按 Id 如上所述排序。保证最多有1个405,如果没有405,Id_405
为null。
Id_406
:Number = 406
的行的 Id
,且在该 400 和 400 之间具有相同的 ParentId
接下来的 400 个,按 Id 如上所述排序。保证最多有1个406。如果没有406,Id_406
为null。
Id_410
:Number = 410
且此 400 与下一个 400 之间 ParentId
相同的行的 Id,排序如上由身份证。保证最多有1个406。如果没有410,则Id_410
为null。
使用上面的示例数据,查询将返回:
ParentId Id Number Id_405 Id_406 Id_410
2997 1145445 400 null null null
2997 1145449 400 null null null
2997 1145577 400 1146518 null null
2999 1145470 400 null null null
2999 1145502 400 null null null
2999 1145504 400 null null null
3016 1145633 400 null null null
3016 1145636 400 null null null
3016 1145677 400 1145686 null null
3037 1145885 400 1145906 null null
3037 1145922 400 null null null
3037 1145925 400 null null null
3162 1147324 400 null null null
3162 1147327 400 null null null
3162 1147329 400 null null null
3162 1147332 400 1147334 null null
3162 1147339 400 1147341 1147345 1147347
请帮忙!
最佳答案
Dan 发布的解决方案实际上并没有产生正确的结果 - 因此我以类似的方式发布了一个似乎可以产生正确结果的解决方案。
WITH r AS (
SELECT t1.parentid
, t1.id
, t1.number
, ISNULL(t2.id,2147483647) as id2
, row = ROW_NUMBER() OVER (PARTITION BY t1.parentid, t1.id ORDER BY t1.id, t2.id)
FROM t t1
LEFT JOIN t t2
ON t1.id < t2.id
AND t1.parentid = t2.parentid
AND t2.number = 400
WHERE t1.number = 400
)
SELECT r.parentid, r.id, r.number, t_405.id as id_405, t_406.id as id_406, t_410.id as id_410
FROM r
LEFT JOIN t t_405
ON t_405.parentid = r.parentid
AND t_405.id BETWEEN r.id AND r.id2
AND t_405.number = 405
LEFT JOIN t t_406
ON t_406.parentid = r.parentid
AND t_406.id BETWEEN r.id AND r.id2
AND t_406.number = 406
LEFT JOIN t t_410
ON t_410.parentid = r.parentid
AND t_410.id BETWEEN r.id AND r.id2
AND t_410.number = 410
WHERE r.row = 1
关于sql-server - SQL Server 2008 R2 : Tricky query - Finding certain rows in segments of rows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30141738/