sql-server - SQL Server 2008 R2 : Tricky query - Finding certain rows in segments of rows

标签 sql-server sql-server-2008-r2

我不知道如何概括地解释这一点,所以请允许我举一个例子。

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 发布的解决方案实际上并没有产生正确的结果 - 因此我以类似的方式发布了一个似乎可以产生正确结果的解决方案。

Fiddle demo

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/

相关文章:

sql-server - TSQL 常量...使用变量还是文字?

.net - 在 DbMigration 中访问 Up 里面的数据库名

sql-server-2008-r2 - 在 SQL Server 2008 R2 中查询 Xml

c# - 遍历数据库表的记录集

c# - 通用数据库字段的数据类型是什么

sql - 将日语字符传递给 SQL Server 存储过程

sql-server - SQL Server需要对数据进行分区,但只有标准版

sql - 根据不同的条件在同一个表上多次连接与在聚合表上连接一次

sql - 如何检查列是否没有null约束?

sql-server - 新的 SQL Server 数据库使用哪个字符集?