【问题标题】:Returning multiple rows from a single row从单行返回多行
【发布时间】:2009-06-30 14:45:32
【问题描述】:

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

给定下表:

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

其中N为整数,编写查询返回如下结果集:

ID、开始、结束
123, 1, 1
123, 1, 2
123, 1, 3
.
.
.
123、1、N

我们使用的平台是 SQL Server 2005,但如果你能用另一种风格的 SQL 做到这一点,我仍然会对解决方案感兴趣。

【问题讨论】:

  • 别忘了选择答案
  • 我不会忘记的。我必须测试解决方案,并根据性能选择最好的解决方案。直到下周我才有机会这样做。

标签: sql-server-2005


【解决方案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

cmets

  • 不要将您的列命名为保留字:“开始”和“结束”,总有一天你会感谢我的。
  • 如果您计划在生产环境中多次运行,create a Numbers table
    并改用此查询:

必须有一个表格 Numbers 才能工作(见上面的链接)

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

它会运行得更好。

【讨论】:

  • 感谢大家的解决方案。这是个好地方!
【解决方案2】:

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

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

使用 Integers.I 上的聚集索引,这应该非常快。您可以在存储过程中预填充整数(基于SELECT max(End) FROM YourTable 的结果)。

【讨论】:

    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 2016-08-16
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多