SQL查询选择具有最小值和最大值的序列号

时间:2018-04-10 02:20:41

标签: sql firebird firebird2.5

在Firebird服务器中,我想根据序列号选择行。对于示例,我有这样的数据:

ID  ROWNUM
1   A1
2   A2
3   A3
4   NULL
5   NULL
6   A6

查询应返回

A1 - A3, A6

我不知道如何选择行,我只能选择A1 - A6,但A4和A5在列表中,即使数据为空。

P.S编辑对不起,我的意思是火鸟服务器不是SQL Server,但是根据我昨天收集的答案,我可以获得如何弄清楚的信息。

4 个答案:

答案 0 :(得分:2)

典型的岛屿+差距问题导致CSV

declare @t table (ID int, ROWNUM char(2))
INSERT INTO @t VALUES 
(1,'A1'),
(2,'A2'),
(3,'A3'),
(4,NULL),
(5,NULL),
(6,'A6');

;with cte as
(
    select  *, grp = ID - row_number() over(order by ROWNUM)
    from    @t
),
cte2 as
(
    select  ROW_NUM = case  when    min(ROWNUM) <> max(ROWNUM)
                then    min(ROWNUM) + ' - ' + max(ROWNUM)
                else    min(ROWNUM)
                end
    from    cte
    where   ROWNUM  is not null
    group by grp
)
select  stuff(
        (select ',' + ROW_NUM
        from    cte2
        for xml path('')),
    1, 1, '')

答案 1 :(得分:1)

我认为您需要单独的 max min 值范围

select Min(rownum) Minrownum, max(rownum) Maxrownum from (
    select *,
             row_number() over (order by rownum) Seq
    from table) t
where rownum is not null
group by (id- Seq)

答案 2 :(得分:1)

@Squirrel建议的非常接近的解决方案,实际上是相同的逻辑 主要用于识别number gaps using SQL

    /*
create table datatbl (ID tinyint identity(1,1), ROWNUM varchar(5))
INSERT INTO datatbl VALUES ('A1'), ('A2'), ('A3'), (NULL), (NULL), ('A6')
*/
;with islands as (
select
    Id,
    RowNum,
    ID - 
    ROW_NUMBER() over (order by 
    (case when ROWNUM is null then null else id end)
    ) grpno
from datatbl
), boundaries as (
select distinct
    grpno, 
    min(id) over (partition by grpno) as minid,
    max(id) over (partition by grpno) as maxid
from islands
where ROWNUM is not null
), fragments as (
select
    b.grpno,
    case when (mi.ROWNUM = ma.ROWNUM) then mi.ROWNUM else mi.ROWNUM + '-' + ma.ROWNUM end as boundary
from boundaries as b
inner join datatbl as mi on mi.ID = b.minid
inner join datatbl as ma on ma.ID = b.maxid
)
select stuff((select ', ' + boundary from fragments for xml path('')),1, 2, '')

使用SQL Server 2017而不是For XML Path string concatenation,也可以使用新的string_agg函数。 最后一个select语句可以替换为以下SQL

select STRING_AGG(boundary, ', ')  Within Group (Order By grpno)
from fragments

答案 3 :(得分:0)

试试这个。

SELECT ROWNUM FROM `your_table_name` WHERE ROWNUM IS NOT NULL ORDER BY ROWNUM DESC;