4

请参阅下面的附件:我的实际数据将存储在表 1 中,我可以创建一个视图来显示表 2 中的数据吗? 在此处输入图像描述

4

6 回答 6

4

是的,这是可能的,它被称为UNPIVOT

对于您的情况:

SELECT period, value, category
FROM 
   (SELECT VendorID, charcge,nocharge
   FROM Table) p
UNPIVOT
   (value FOR category IN 
      (charge,nocharge)
)AS unpvt;
于 2013-09-27T04:50:29.227 回答
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

附加信息:

在 Profiler 的帮助下检测潜在的瓶颈

于 2013-09-27T05:21:20.267 回答
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

于 2013-09-27T05:35:33.537 回答
3

请参阅PIVOT/UNPIVOT了解您需要的内容

于 2013-09-27T04:55:06.807 回答
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;
于 2013-09-27T04:53:25.180 回答
0

这是一个菜鸟的解决方案,因为我是菜鸟。我不知道它是否有机会在速度方面与 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 小提琴

于 2013-09-27T06:40:39.587 回答