将 header 行扩展为多个 child 行
Expand header row into multiple child rows
在我的 SQL 数据库中,我有一个 table 代表门票书 [Books] 其中一本书中的门票数量可能会有所不同。
这由两列表示 [Books].[StartNo]
和 [Books].[BookSize]
我需要实现的是 select 语句,该语句为该书中的每张票重复 table [书籍] 中的每一行,并带有一个额外的计算列,显示该票的票号行。
所以从
--------+---------+----------
Book | StartNo | BookSize
--------+---------+----------
Book 1 | 1 | 3
Book 2 | 4 | 4
Book 3 | 19 | 4
像这样
--------+---------+----------+----------
Book | StartNo | BookSize | TicketNo
--------+---------+----------+----------
Book 1 | 1 | 3 | 1
Book 1 | 1 | 3 | 2
Book 1 | 1 | 3 | 3
Book 2 | 4 | 4 | 4
Book 2 | 4 | 4 | 5
Book 2 | 4 | 4 | 6
Book 2 | 4 | 4 | 7
Book 3 | 19 | 4 | 19
Book 3 | 19 | 4 | 20
Book 3 | 19 | 4 | 21
Book 3 | 19 | 4 | 22
我只是不太确定从哪里开始。
试试这个:
;WITH Counts AS (
SELECT Max(StartNo + BookSize) AS TotalBookSize
FROM t
), CTE(Tickets) AS (
SELECT 1
UNION ALL
SELECT Tickets + 1
FROM CTE
WHERE Tickets < (SELECT TotalBookSize FROM Counts)
)
SELECT *
FROM t JOIN CTE ON CTE.Tickets BETWEEN t.StartNo AND t.StartNo + t.BookSize - 1
你需要一个数字列表,并将其与书籍合并table
select b.*, number
from Books b
join master.dbo.spt_values v on v.number between b.StartNo AND b.StartNo+b.BookSize-1
使用tally table
WITH lv0 AS (SELECT 0 g UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0)
,lv1 AS (SELECT 0 g FROM lv0 a CROSS JOIN lv0 b) --10 * 10 = 100
,lv2 AS (SELECT 0 g FROM lv1 a CROSS JOIN lv0 b) --100 * 10 = 1000
,Tally (num) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM lv2)
SELECT (num+StartNo-1) as TicketNo, *
FROM Tally
CROSS JOIN Yourtable
WHERE num <= booksize
ORDER BY book
在我的 SQL 数据库中,我有一个 table 代表门票书 [Books] 其中一本书中的门票数量可能会有所不同。
这由两列表示 [Books].[StartNo]
和 [Books].[BookSize]
我需要实现的是 select 语句,该语句为该书中的每张票重复 table [书籍] 中的每一行,并带有一个额外的计算列,显示该票的票号行。
所以从
--------+---------+----------
Book | StartNo | BookSize
--------+---------+----------
Book 1 | 1 | 3
Book 2 | 4 | 4
Book 3 | 19 | 4
像这样
--------+---------+----------+----------
Book | StartNo | BookSize | TicketNo
--------+---------+----------+----------
Book 1 | 1 | 3 | 1
Book 1 | 1 | 3 | 2
Book 1 | 1 | 3 | 3
Book 2 | 4 | 4 | 4
Book 2 | 4 | 4 | 5
Book 2 | 4 | 4 | 6
Book 2 | 4 | 4 | 7
Book 3 | 19 | 4 | 19
Book 3 | 19 | 4 | 20
Book 3 | 19 | 4 | 21
Book 3 | 19 | 4 | 22
我只是不太确定从哪里开始。
试试这个:
;WITH Counts AS (
SELECT Max(StartNo + BookSize) AS TotalBookSize
FROM t
), CTE(Tickets) AS (
SELECT 1
UNION ALL
SELECT Tickets + 1
FROM CTE
WHERE Tickets < (SELECT TotalBookSize FROM Counts)
)
SELECT *
FROM t JOIN CTE ON CTE.Tickets BETWEEN t.StartNo AND t.StartNo + t.BookSize - 1
你需要一个数字列表,并将其与书籍合并table
select b.*, number
from Books b
join master.dbo.spt_values v on v.number between b.StartNo AND b.StartNo+b.BookSize-1
使用tally table
WITH lv0 AS (SELECT 0 g UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0)
,lv1 AS (SELECT 0 g FROM lv0 a CROSS JOIN lv0 b) --10 * 10 = 100
,lv2 AS (SELECT 0 g FROM lv1 a CROSS JOIN lv0 b) --100 * 10 = 1000
,Tally (num) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM lv2)
SELECT (num+StartNo-1) as TicketNo, *
FROM Tally
CROSS JOIN Yourtable
WHERE num <= booksize
ORDER BY book