首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Server中检索排序列值

在Server中检索排序列值
EN

Stack Overflow用户
提问于 2016-06-13 07:03:41
回答 2查看 72关注 0票数 1

我拥有的:

我有个专栏

代码语言:javascript
运行
复制
ID  SerialNo
1   101
2   102
3   103
4   104
5   105
6   116
7   117
8   118
9   119
10  120

这仅仅是10行虚拟行。实际的表有超过10万行。

我想要的东西:

一种类似于任何排序技术的方法或公式,它可以为每个子系列返回SerialNo列的起始元素和结束元素。例如

预期结果: 101-105,115-120

以上结果中的逗号分隔并不重要,只有开始元素和结束元素才是重要的。

我尝试过的:

我是通过PL/SQL编程完成的,我运行了一个循环,在这个循环中,我将开始和结束元素存储在一个表中。但因为没有。对于行(超过100,000),查询执行大约需要2分钟。

我还搜索了SQL Server的一些排序技术,但一无所获。因为呈现每一行所需的时间是排序算法的两倍。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-13 08:20:09

只需找到每个系列的开始和结束就很简单了:

代码语言:javascript
运行
复制
declare @t table (ID int not null, SerialNo int not null)
insert into @t(ID,SerialNo) values
(1 ,101),    (2 ,102),    (3 ,103),
(4 ,104),    (5 ,105),    (6 ,116),
(7 ,117),    (8 ,118),    (9 ,119),
(10,120)

;With Starts as (
    select t1.SerialNo,ROW_NUMBER() OVER (ORDER BY t1.SerialNo) as rn
    from
        @t t1
            left join
        @t t1_no
            on t1.SerialNo = t1_no.SerialNo + 1
    where t1_no.ID is null
), Ends as (
    select t1.SerialNo,ROW_NUMBER() OVER (ORDER BY t1.SerialNo) as rn
    from
        @t t1
            left join
        @t t1_no
            on t1.SerialNo = t1_no.SerialNo - 1
    where t1_no.ID is null
)
select
    s.SerialNo as StartSerial,
    e.SerialNo as EndSerial
from
    Starts s
        inner join
    Ends e
        on s.rn = e.rn

逻辑是,Start是一个行,其中没有一个行比当前行少一个行,而一个End是一个行,其中没有一个行比当前行多一个SerialNo行。

如果SerialNo列上没有索引,这可能仍然表现不佳。

结果:

代码语言:javascript
运行
复制
StartSerial EndSerial
----------- -----------
101         105
116         120

希望这是可以接受的,因为您似乎并不关心具体的结果是什么。它也是以设定为基础的。

票数 0
EN

Stack Overflow用户

发布于 2016-06-13 07:17:34

假设每个子系列应该包含5个记录,我使用下面的sql获得了预期的结果。我希望这能帮到你。

代码语言:javascript
运行
复制
DECLARE @subSeriesRange INT=5;

CREATE TABLE #Temp(ID INT,SerialNo INT);

INSERT INTO  #Temp VALUES(1,101),
(2,102),
(3,103),
(4,104),
(5,105),
(6,116),
(7,117),
(8,115),
(9,119),
(10,120);

SELECT STUFF((SELECT CONCAT(CASE ID%@subSeriesRange WHEN 1 THEN ',' ELSE '-' END,SerialNo)
        FROM #Temp
        WHERE ID%@subSeriesRange = 1 OR ID%@subSeriesRange=0
        ORDER BY ID
        FOR XML PATH('')),1,1,''
        );

DROP TABLE #Temp;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37783609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档