分组记录后的SQL获取范围

时间:2014-09-24 07:28:18

标签: c# sql asp.net sql-server

我有一个SQL表,其输入表具有以下记录

srno|dispatch|PrintedPagesfromNo|PrintedPagestoNo|done
----+--------+------------------+----------------+----
1   |Post    |1                 |5               |N         
2   |Post    |6                 |10              |N         
3   |Post    |11                |13              |N         
4   |Courier |14                |16              |N         
5   |Post    |17                |20              |N         
6   |Courier |21                |25              |N         
7   |Courier |26                |30              |N         
8   |Post    |31                |40              |N         
9   |Courier |41                |50              |N       

我想写一个SQL查询来生成输出,如下所示

Dispatch|PrintedPagesfromNo|PrintedPagestoNo
--------+------------------+----------------
Post    |1                 |13
Post    |17                |20
Post    |31                |40
Courier |14                |16
Courier |21                |30
Courier |41                |50

要求是在对顺序条目进行分组后显示用户有限的范围。

生成上表后,我将使用C#在ASP.net网站上向用户显示相同内容。

此外,上表在运行时将有多个插入。

1 个答案:

答案 0 :(得分:0)

更新:随着评论的澄清,我怀疑你需要使用递归CTE来做到这一点:

with my_cte ([Root], dispatch, PrintedPagesfromNo, PrintedPagestoNo)
as (
  select h.srno, h.dispatch, h.PrintedPagesfromNo, h.PrintedPagestoNo
  from #foo h
  where not exists(
      select 1 from #foo l
      where h.dispatch = l.dispatch and h.PrintedPagesfromNo = l.PrintedPagestoNo + 1)
  union all
  select l.[Root], l.dispatch, h.PrintedPagesfromNo, h.PrintedPagestoNo
  from my_cte l
  inner join #foo h on h.dispatch = l.dispatch
                    and h.PrintedPagesfromNo = l.PrintedPagestoNo + 1
)
select dispatch, MIN(PrintedPagesfromNo) as PrintedPagesfromNo,
                 MAX(PrintedPagestoNo) as PrintedPagestoNo
from my_cte
group by [Root], dispatch
ORDER  BY dispatch DESC, MIN(PrintedPagesfromNo)

(用您的表名替换#foo

注意h表示“更高”,l表示“更低”;这可以通过首先找到没有相同dispatch和相邻范围的先前下块的块,然后每次为同一dispatch递归查找相邻块然后根据群体来寻找整体范围。


这很有趣:

WITH batches AS (
    SELECT *, srno - ROW_NUMBER() OVER (PARTITION BY dispatch ORDER BY srno) AS batch
    FROM   [YourTableName])

SELECT dispatch,
       MIN(PrintedPagesfromNo) AS PrintedPagesfromNo,
       MAX(PrintedPagestoNo) AS PrintedPagestoNo
FROM   batches
GROUP  BY dispatch, batch
ORDER  BY dispatch DESC, MIN(PrintedPagesfromNo)

请注意,这假定srno可靠连续。没有它,您需要额外的ROW_NUMBER() OVER (ORDER BY srno)

WITH batches AS (
    SELECT x.dispatch, x.PrintedPagesfromNo, x.PrintedPagestoNo,
       _row - ROW_NUMBER() OVER (PARTITION BY dispatch ORDER BY _row) AS batch
    FROM   (SELECT *, ROW_NUMBER() OVER (ORDER BY srno) as _row
            FROM [YourTableName]) x)

SELECT dispatch,
       MIN(PrintedPagesfromNo) AS PrintedPagesfromNo,
       MAX(PrintedPagestoNo) AS PrintedPagestoNo
FROM   batches
GROUP  BY dispatch, batch
ORDER  BY dispatch DESC, MIN(PrintedPagesfromNo)