在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,但是根据我昨天收集的答案,我可以获得如何弄清楚的信息。答案 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;