SQL Server 2012 Свернуть/развернуть два столбца в один?

Фактическая таблица имеет около 6 миллионов строк, num1 и num2 в каждой строке представляют собой числовые границы. Мне нужно преобразовать набор из двух столбцов в один столбец и применить к каждой из двух строк, которые ранее использовали одну строку. Ниже небольшой образец. Я просмотрел примеры Unpivot, но ничего не подходит мне. Может ли кто-нибудь порекомендовать правильный путь? Я понимаю, что в итоге я получу 12 миллионов строк.

Спасибо.

declare @orig table ( num1 bigint , num2 bigint , metakey tinyint )
insert into @orig 
select 7216,7471  , 0
union all
select 7472,8239  , 1
union all
select 8240,9263  , 2
union all
select 9264,11311 , 3


declare @dest table ( allnum bigint , metakey tinyint )

    -- Wanted result set:
/*
    select * from @dest
    7216        0
    7471        0
    7472        1
    8239        1
    8240        2
    9263        2
    9264        3
    11311       3
*/

Я понимаю, что это работает для моего примера табличной переменной, но для действительно большого набора это не пахнет правильно:

insert into @dest
select num1 , metakey
from @orig
union all 
select num2 , metakey
from @orig
order by 1

person Snowy    schedule 24.10.2013    source источник
comment
Нет, других способов сделать это нет.   -  person Igor Borisenko    schedule 24.10.2013


Ответы (3)


Отменить поворот, чтобы делать то, что вы хотите .

select u.allnum,
       u.metakey
from @orig as o
  unpivot (allnum for col in (o.num1, o.num2)) as u

По сравнению с запросом на объединение, который у вас уже есть, это должно быть быстрее, потому что он будет сканировать таблицу только один раз, а не дважды.

person Mikael Eriksson    schedule 24.10.2013
comment
Это работает, но мне пришлось добавить ключевое слово Distinct в более позднем выражении, чтобы избавиться от дубликатов в крайнем случае (не в моем исходном посте) со значениями 7214,7214, поскольку мой Union неявно их отфильтровал. Спасибо. - person Snowy; 24.10.2013

Это можно легко сделать с помощью перекрестного применения

select allnum,metakey from @orig cross apply (values(num1 ), (num2)) x(allnum)
person sahalMoidu    schedule 24.10.2013

Если вы можете выполнить двухэтапный процесс, вы можете сделать это:

insert @dest (bigint, metakey)
    select num1, metakey from @orig

insert @dest (bigint, metakey)
    select num2, metakey from @orig

Если это не вариант, вы можете сделать то же самое, выбрав из производной таблицы, которая будет состоять из объединения двух вариантов выбора выше.

person KCevMart    schedule 24.10.2013
comment
Извините, я не видел ваш второй блок текста, прежде чем я ответил. - person KCevMart; 24.10.2013
comment
Вы можете удалить свой комментарий, если хотите. - person Igor Borisenko; 24.10.2013