我想編寫一個腳本,有兩個不同的領域,並列出了哪些值將在兩者之間在IE擴大了全範圍的兩個字段
之間的列表ID|Start#|End#
1 |1 |5
2 |6 |8
3 |9 |10
將顯示爲
ID |FullRange
1 |1
1 |2
1 |3
1 |4
1 |5
2 |6
2 |7
2 |8
3 |9
3 |10
我想編寫一個腳本,有兩個不同的領域,並列出了哪些值將在兩者之間在IE擴大了全範圍的兩個字段
之間的列表ID|Start#|End#
1 |1 |5
2 |6 |8
3 |9 |10
將顯示爲
ID |FullRange
1 |1
1 |2
1 |3
1 |4
1 |5
2 |6
2 |7
2 |8
3 |9
3 |10
您可以使用遞歸來做到這一點。
WITH cte ([ID], [END#], FullRange)
AS
(
-- Anchor member definition
SELECT ee.[ID]
,ee.[END#]
,ee.[START#] as FullRange
FROM [master].[dbo].[test] ee
where ee.[START#] < ee.[END#]
UNION ALL
-- Recursive member definition
SELECT e.[ID]
,e.[END#]
,FullRange +1
FROM [master].[dbo].[test] e inner join cte
on e.id = cte.id and FullRange +1 <= cte.END#
)
-- Statement that executes the CTE
SELECT ID,FullRange
FROM cte
ORDER BY ID
結果如下圖所示:
ID FullRange
1 1
1 2
1 3
1 4
1 5
2 6
2 7
2 8
3 9
3 10
您可以使用Tally Table從生成數[Start#]
到[End#]
:
WITH E1(N) AS(-- 10^1 = 10 rows
SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10^2 = 100 rows
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10^4 = 10,000 rows
CteTally(N) AS(
SELECT TOP(SELECT MAX([End#] - [Start#]) + 1 FROM Tbl)
ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) - 1
FROM E4
)
SELECT
t.ID,
FullRange = t.[Start#] + ct.N
FROM Tbl t
CROSS JOIN CteTally ct
WHERE t.[Start#] + ct.N <= t.[End#]
ORDER BY t.ID, FullRange
declare @tbl table (id int, start int, [end] int)
insert @tbl values (1, 1, 5), (2, 6, 8), (3, 9 , 10);
;with t(c) as
(
select * from (values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) a(b)
),
x(y) as
(
select t1.c * 100 + t2.c * 10 + t3.c
from t t1
cross join t t2
cross join t t3
)
select t.id, x.y
from x
join @tbl t on t.start <= x.y and t.[end] >= x.y
order by t.id, x.y
請告訴我們您的最佳嘗試。 –
創建一個商店presodure或表函數誰recive這兩個值,並在de函數內建立一個WHILE LOOP插入每個值在表變量,然後選擇所有記錄插入表變量 – Byron
@Byron雖然這將是一種方式做到這一點,我不會推薦它。如果可以以基於集合的方式完成,則應避免使用「CURSOR」或「WHILE」循環。 –