如何在sql服务器中将连续的序号依次排列成两列或多列?
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);
另一种看起来不那么混乱的 CASE
和 TOP
方法是使用几个 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)
。
或者,set-based 使用 window 函数的解决方案:
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
这种方法的积极方面,它可以很好地扩展并且对要处理的行数没有上限
假设您从 table 一栏开始,您可以使用:
select min(number), max(number)
from sample_data
group by floor( (number - 1) / 2);
我想使用 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);
另一种看起来不那么混乱的 CASE
和 TOP
方法是使用几个 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)
。
或者,set-based 使用 window 函数的解决方案:
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
这种方法的积极方面,它可以很好地扩展并且对要处理的行数没有上限
假设您从 table 一栏开始,您可以使用:
select min(number), max(number)
from sample_data
group by floor( (number - 1) / 2);