2009-06-30 5 views
2

Это не может быть возможно, но я думал, что бросить его здесь:Возвращаясь несколько строк из одной строки

Учитывая следующую таблицу:

ID, Begin, End
123, 1 , N

где N представляет собой целое число, написать запрос, возвращающий следующий результирующий набор:

ID, начало, конец
123, 1, 1
123, 1, 2
123, 1, 3
.
.
.
123, 1, N

Платформа мы используем, SQL Server 2005, но если вы можете сделать это с другим привкусом SQL, я бы до сих пор заинтересованы в решении.

+0

не забудьте указать ответ –

+0

Я не забуду. Я должен протестировать решения и выбрать лучший из них на основе производительности. У меня не будет возможности сделать это до следующей недели. – 2009-07-02 20:12:28

ответ

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 

комментарии

  • не называют в ваших колонках зарезервированы слова: «begin» и «end», вы когда-нибудь поблагодарите меня.
  • , если вы планируете запустить это в производство много раз, create a Numbers table
    и использовать этот запрос вместо:

должны иметь таблицу чисел, прежде чем это будет работать (см ссылку выше)

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 

будет работать лучше.

+1

Спасибо, всем, за решения. Это отличное место! – 2009-07-01 12:10:03

1

Учитывая некоторые (теоретически бесконечно, но вы можете предварительно заполнить) стол Целых, содержащая все целые числа, ответ достаточно прост:

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

С кластерным индексом Integers.I, это должно быть достаточно быстро. Вы можете предварительно заполнить целые числа в хранимой-proc (на основе результата от SELECT max(End) FROM YourTable).

1

Это будет работать до 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