繁体   English   中英

如何在sql server中将连续的序列号按顺序排列成两列或多列?

[英]How to arrange continuous serial number in to two or multiple column sequentially in sql server?

我想使用 MS Sql-Server 查询以两列格式打印或显示 1 到 10 或任何最大数字。 就像下面附加的屏幕截图图像一样。

在此处输入图片说明

所以请提出任何建议。

所以我得到了这个解决方案,如下所示......

declare @t table
(
id int identity(1,1),
Number_1 int,
Number_2 int
)


declare @min int=1
declare @max int=10
declare @a int=0;
declare @id int=0


while(@min<=@max)
begin

if(@a=0)
begin
insert into @t
select @min,null
set @a=1
end
else if(@a=1)
begin
select top 1 @id=id from @t order by id desc
update @t set Number_2=@min where id=@id
set @a=0
end

set @min=@min+1
end

select Number_1,Number_2 from @t

使用几个内联计数会比WHILE快得多。 此版本最多可包含 1000 个整数(500 行):

DECLARE @Start int = 1,
        @End int = 99;

SELECT TOP(CONVERT(int,CEILING(((@End*1.) - @Start + 1)/2)))
       (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1)*2 + @Start AS Number1,
       CASE WHEN (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1)*2 + @Start +1 <= @End THEN (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1)*2 + @Start +1 END AS Number2
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N1(N)
     CROSS APPLY (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N2(N)
     CROSS APPLY (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N3(N);

使用CASETOP看起来不那么混乱的另一种方法是使用几个 CTE:

WITH Tally AS(
    SELECT TOP(@End - @Start + 1)
           ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 + @Start AS I
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N1(N)
         CROSS APPLY (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N2(N)
         CROSS APPLY (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N3(N)),
Numbers AS(
    SELECT I AS Number1,
           LEAD(I) OVER (ORDER BY I) AS Number2
    FROM Tally)
SELECT Number1,
       Number2
FROM Numbers 
WHERE Number1 % 2 = @Start % 2;

我喜欢为此使用递归查询:

with cte (num1, num2) as (
    select 1, 2 
    union all
    select num1 + 2, num2 + 2 from cte where num2 < 10
)
select * from cte order by num1

您可以使用 cte 的递归成员中的不等式条件控制最大数。

如果需要生成超过 100 行,则需要在查询的最后添加option(maxrecursion 0)

或者,使用窗口函数的基于集合的解决方案:

use tempdb

;with sample_data as (
select 1 as val union all
select 2 union all
select 3 union all
select 4 union all
select 5 union all
select 6 union all
select 7 union all
select 8 union all
select 9 union all
select 10 
) 

, sample_data_split  as
(
    select 
        val
    ,   2- row_number() over (order by val) % 2 as columnid
    ,  NTILE((select count(*) / 2  from sample_data) ) over (order by val) groupid
    from sample_data
) 

sample_data_split的中间结果是:

val columnid    groupid
1   1   1
2   2   1
3   1   2
4   2   2
5   1   3
6   2   3
7   1   4
8   2   4
9   1   5
10  2   5

然后将结果集转换为所需的格式:

select 
    min(case when columnid = 1 then val end) as column1
,   min(case when columnid = 2 then val end) as column2
from sample_data_split
group by groupid
column1 column2
1   2
3   4
5   6
7   8
9   10

这些 CTE 可以合并到一个 SELECT 中:

select 
    min(case when columnid = 1 then val end) as column1
,   min(case when columnid = 2 then val end) as column2
from 
(
    select 
        val
    ,   2- row_number() over (order by val) % 2 as columnid
    ,  NTILE((select count(*) / 2  from sample_data) ) over (order by val) groupid
    from sample_data
) d
group by groupid

这种方法的积极方面是,它可以很好地扩展并且对要处理的行数没有上限

假设您从一个只有一列的表开始,您可以使用:

select min(number), max(number)
from sample_data
group by floor( (number - 1) / 2);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM