从单个行返回多行(Returning multiple rows from a single row

2019-09-17 07:44发布

这是不可能的,但我想我会扔在这里:

如下表:

ID,开始,结束
123,1,N

其中n是一个整数,编写一个查询返回以下结果集:

ID,开始,结束
123,1,1
123,1,2
123,1,3-



123,1,N

我们所使用的平台是SQL Server 2005中,但如果你可以用SQL的另一种风味做到这一点,我仍然有兴趣在溶液中。

Answer 1:

尝试这个:

create table #smalltable (id int, [begin] int, [end] int)
insert into #smalltable values (123,1,4)
insert into #smalltable values (124,1,12)
insert into #smalltable values (125,1,7)

;WITH digits (d) AS (
    SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
    SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION
    SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION
    SELECT 0)
SELECT
    s.id, s.[begin], n.Number AS [End]
    FROM (SELECT i.d + ii.d * 10 + iii.d * 100 + iv.d * 1000 +
              v.d * 10000 + vi.d * 100000 AS Number
              FROM digits            i
                  CROSS JOIN digits  ii
                  CROSS JOIN digits  iii
                  CROSS JOIN digits  iv
                  CROSS JOIN digits  v
                  CROSS JOIN digits  vi
         ) AS N
        INNER JOIN #smalltable                                    s  ON 1=1
        INNER JOIN (SELECT MAX([end]) AS MaxEnd FROM #smalltable) dt ON 1=1
   WHERE n.Number > 0 AND n.Number<=dt.MaxEnd
    AND n.Number<=s.[end]
   ORDER BY s.id,n.Number

评论

  • 不命名您的栏保留字:“开始”和“结束”,你会感谢我的一天。
  • 如果您打算在生产环境中运行很多次, 创建一个数字表
    并使用此查询代替:

必须有一个表格中的数字在此之前将工作(见上面的链接)

SELECT
    s.id,s.[begin],n.Number AS [End]
    FROM Numbers                n
        INNER JOIN #smalltable  s ON 1=1
   WHERE  n.Number > 0 AND n.Number<=s.[end]
   ORDER BY s.id,number

它会运行得更好。



Answer 2:

鉴于一些(理论上是无限的,但你可以预先填充)表整数,包含所有整数,答案相当简单:

SELECT ID, Begin, I FROM YourTable, Integers
WHERE I <= Begin AND I >= End

随着Integers.I一个聚集索引,这应该是非常快。 你可以预填充在存储进程内(基于结果的整数SELECT max(End) FROM YourTable )。



Answer 3:

这将工作到99,999,你可以很容易地修改它来添加更多号码。 它不需要预先存在的数字表,并没有存储过程,并且仍然非常快。 至少SQL Server 2000的作品上了,很容易移植到SQL的其他口味:

select MyTable.ID, MyTable.[Begin], n.N
from (
    select 123 as ID, 1 as [Begin], 9 as [End]
) MyTable
cross join (
    select a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) + (10000 * e.a) as N
    from (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as a
    cross join (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as b
    cross join (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as c
    cross join (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as d
    cross join (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as e
) n
where n.N > 0
    and n.N <= MyTable.[End]
order by n.N


文章来源: Returning multiple rows from a single row