【发布时间】:2019-08-01 07:03:05
【问题描述】:
我需要您的帮助才能从给定的输入中获得以下输出。
输入
表:Sample
ID
---
1
2
3
4
输出
ID
---
1
2
2
3
3
3
4
4
4
4
【问题讨论】:
标签: sql sql-server tsql sql-server-2012
我需要您的帮助才能从给定的输入中获得以下输出。
输入
表:Sample
ID
---
1
2
3
4
输出
ID
---
1
2
2
3
3
3
4
4
4
4
【问题讨论】:
标签: sql sql-server tsql sql-server-2012
使用自联接:
select s.id
from sample s inner join sample ss
on s.id >= ss.id
order by s.id
请参阅demo。
结果:
> | id |
> | -: |
> | 1 |
> | 2 |
> | 2 |
> | 3 |
> | 3 |
> | 3 |
> | 4 |
> | 4 |
> | 4 |
> | 4 |
如果 id 之间存在间隙或最小值大于 1,您可以使用递归 CTE:
declare @maxid int = (select max(id) from sample);
with allids AS (
select 1 id
union all
select id + 1 FROM allids where id + 1 <= @maxid
)
select s.id
from sample s inner join allids ss
on s.id >= ss.id
order by s.id
请参阅demo。
INSERT INTO Sample ( ID ) VALUES ( 2 ), ( 3 ), ( 5 ), ( 7 ), ( 9 );
结果:
> | id |
> | -: |
> | 2 |
> | 2 |
> | 3 |
> | 3 |
> | 3 |
> | 5 |
> | 5 |
> | 5 |
> | 5 |
> | 5 |
> | 7 |
> | 7 |
> | 7 |
> | 7 |
> | 7 |
> | 7 |
> | 7 |
> | 9 |
> | 9 |
> | 9 |
> | 9 |
> | 9 |
> | 9 |
> | 9 |
> | 9 |
> | 9 |
使用此解决方案您不必对表的 id 进行硬编码(可以有多少个?),即使您添加或删除 id 也可以使用.
【讨论】:
这是一个解决方案
SELECT ID
FROM (VALUES (1), (2), (3), (4)) T(ID)
CROSS APPLY
(
SELECT 1 N
FROM master..spt_values
WHERE [Type] = 'P'
AND
[Number] < T.ID
) TT(V);
为什么使用
spt_values而不是自加入?
例如,如果您没有值 3
SELECT T.ID
FROM (VALUES (1), (2), (4)) T(ID)
INNER JOIN (VALUES (1), (2), (4)) TT(ID)
ON T.ID >= TT.ID
ORDER BY T.ID;
slef-join 将重复值4 三次而不是四次。
使用spt_values 将保证每个数字都会按预期重复。
SELECT T.ID
FROM (VALUES (1), (2), (4)) T(ID)
CROSS APPLY
(
SELECT 1 N
FROM master..spt_values
WHERE [Type] = 'P'
AND
[Number] < T.ID
) TT(V);
如果你有很多数字,那么你可以使用 Tally Table 作为
CREATE VIEW Tally (N) AS
SELECT ROW_NUMBER() OVER(ORDER BY(SELECT 0)) N
FROM (
(VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)) T1(N) --10
CROSS JOIN
(VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)) T2(N) --100
CROSS JOIN
(VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)) T3(N) --1000
CROSS JOIN
(VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)) T5(N) --10000
);
SELECT T.V
FROM (VALUES (1), (2), (4), (80), (4000)) T(V)
CROSS APPLY (SELECT N FROM Tally WHERE N <= T.V) TBL
ORDER BY T.V;
【讨论】: