是否有可能创建一个从“水平”到“垂直”的SQL视图

时间:2013-09-27 04:48:39

标签: sql sql-server

请参阅下面的附件: 我的实际数据将存储在表1中,我可以创建一个显示表2的数据的视图吗? enter image description here

6 个答案:

答案 0 :(得分:4)

是的,它可以被称为UNPIVOT

对于你的情况:

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

答案 1 :(得分:3)

请参阅PIVOT/UNPIVOT了解您的需求

答案 2 :(得分: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

答案 3 :(得分:3)

虽然其他答案已经足够好了,但有时候能够不明确指定所有列名称是有用的,所以你可以使用xml技巧来取消行:

;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

答案 4 :(得分: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;

答案 5 :(得分: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