2013-09-27 3 views
4

, пожалуйста, см. Мое прилагаемое ниже: Мои фактические данные будут храниться в таблице 1, можно ли создать представление, отображающее данные, такие как таблица 2? enter image description hereВозможно ли создать представление sql из «горизонтального» в «вертикальное»

+0

Рассмотрите возможность использования функции PIVOT –

+0

проверить мой ответ –

ответ

4

Да, это возможно, и это называется UNPIVOT

В вашем случае:

SELECT period, value, category 
FROM 
    (SELECT VendorID, charcge,nocharge 
    FROM Table) p 
UNPIVOT 
    (value FOR category IN 
     (charge,nocharge) 
)AS unpvt; 
2

Пожалуйста, попробуйте использовать UNPIVOT.

SELECT * 
FROM 
    (SELECT * FROM YourTable) p 
UNPIVOT 
    (Value FOR Category IN 
     (change, no_change) 
)AS unpvt; 

Запрос может быть выполнен в виде зрения, используя следующий запрос:

CREATE VIEW MyView AS 
SELECT * 
FROM 
    (SELECT * FROM YourTable) p 
    UNPIVOT 
     (Value FOR Category IN 
      (change, no_change) 
)AS unpvt; 
3

запроса:

DECLARE @temp TABLE 
(
     period VARCHAR(50) 
    , charge INT 
    , no_charge INT 
) 

INSERT INTO @temp (period, charge, no_charge) 
VALUES 
    ('period 1', 100, 300), 
    ('period 2', 200, 400), 
    ('period 3', 300, 200), 
    ('period 4', 500, 200) 

SELECT t.* 
FROM @temp 
CROSS APPLY (
    VALUES 
    (period, charge, 'charge'), 
    (period, no_charge, 'no_charge') 
) t(period, value, category) 

Вывод:

period    value  category 
-------------------- ----------- --------- 
period 1    100   charge 
period 1    300   no_charge 
period 2    200   charge 
period 2    400   no_charge 
period 3    300   charge 
period 3    200   no_charge 
period 4    500   charge 
period 4    200   no_charge 

Выполнение плана:

tt

Дополнительная информация:

Detecting Potential Bottlenecks with the help of Profiler

+2

+1 Я на самом деле, как 'поперечного apply' запроса гораздо больше, чем' unpivot' (и агрегатов более 'pivot'). Он выглядит намного более удобным для меня. –

3

В то время как другие ответы достаточно хорошо, иногда это USEF уль, чтобы иметь возможность явно не указать все имена столбцов, так что вы можете использовать XML трюк UNPIVOT строки:

;with cte as (
    select t.period, (select t.* for xml raw('row'), type) as Data 
    from @temp as t 
), cte2 as (
    select 
     c.period, 
     t.c.value('local-name(.)', 'nvarchar(128)') as category, 
     t.c.value('.', 'nvarchar(max)') as value 
    from cte as c 
     outer apply c.Data.nodes('row/@*[local-name() != "period"]') as t(c) 
) 
select * 
from cte2 

Для очень больших таблиц он может выполнять несколько хуже, чем обычный SQL (но я использую этот подход все время обновления/вставки тысяч строк, и это хорошо работает для меня). OTOH вам не нужно изменять запрос при добавлении новых столбцов в таблицу. Я попытался рассмотреть плюсы и минусы этого подхода здесь - SQL Server : Columns to Rows.

sql fiddle demo

+1

+1 - действительно отличный ответ. – Devart

0

Вот noobish сог решение я нуб. Я не знаю, есть ли у него шансы против ответов, отправленных SQL-мастерами раньше с точки зрения скорости.

select period,value,category from (
select case period when 'period 1' then charge 
when 'period 2' then charge 
when 'period 3'then charge 
when 'period 4'then charge 
end as value,'charge' as category, 
case period when 'period 1' then 'period 1' 
    when 'period 2' then 'period 2' 
    when 'period 3' then 'period 3' 
    when 'period 4' then 'period 4' 
    end as period 
from test 

union all 

select case period when 'period 1' then nocharge 
when 'period 2' then nocharge 
when 'period 3'then nocharge 
when 'period 4'then nocharge 
end as value,'no charge' as category, 
case period when 'period 1' then 'period 1' 
    when 'period 2' then 'period 2' 
    when 'period 3' then 'period 3' 
    when 'period 4' then 'period 4' 
    end as period 

from test 
)z 
order by period 

SQL FIDDLE

Смежные вопросы