SQL Transpose \ Pivot

时间:2014-01-20 05:28:30

标签: sql sql-server pivot-table transpose

我正在尝试对原始表中的各个项目进行每周摘要。 查询应为每个指定的项类型返回1行(即门,Windows等) 如果没有返回任何项,则应返回空值

Original Table
+-------+-----------+----------+-----------+-------+------+
|ITEMID | Date      |ItemType  |Account No |Amt    | Desc |
+-------+-----------+----------+-----------+-------|------|
|10     |2014-01-01 | Doors    |12345      |10     | ab   |
+-------+-----------+----------+-----------+-------|------|
|10     |2014-01-02 | Doors    |12345      |10     | cd   |
+-------+-----------+----------+-----------+-------|------|
|10     |2014-01-03 | Doors    |12345      |10     | ef   |
+-------+-----------+----------+-----------+-------|------|
|10     |2014-01-04 | Doors    |12345      |10     | gh   |
+-------+-----------+----------+-----------+-------|------|
|10     |2014-01-05 | Doors    |12345      |10     | ij   |
+-------+-----------+----------+-----------+-------|------|
|10     |2014-01-06 | Doors    |12345      |10     | kl   |
+-------+-----------+----------+-----------+-------|------|
|10     |2014-01-07 | Doors    |12345      |10     | mn   |
+-------+-----------+----------+-----------+-------|------|

target table:

+----------+-----------+------+-------+------+-------+------+-------+------+-------+------+-------+------+-------+------+-------+
| ItemType | AccountNo | Amt1 | DESC1 | Amt2 | Desc2 | Amt3 | Desc3 | Amt4 | Desc4 | Amt5 | Desc5 | Amt6 | Desc6 | Amt7 | Desc7 |
+----------+-----------+------+-------+------+-------+------+-------+------+-------+------+-------+------+-------+------+-------+
| Doors    | 1234      | 10   |  ab   | 11   |  cd   | 12   |  ef   | 13   |  gh   | 14   |  ij   | 15   |  kl   | 16   |  mn   |
+----------+-----------+------+-------+------+-------+------+-------+------+-------+------+-------+------+-------+------+-------+

我能够根据下面的答案把这个任务的下面的查询放在一起,但是有更好,更有效的方法吗?

  SELECT t1.Amt AS amt1, t1.desc AS desc1, t2.amt AS amt2, t2.desc AS desc2,t3.Amt AS amt3, t3.desc AS desc3 

t4.amt AS amt4,t4.desc AS desc4,t5.amt AS amt5,t5.desc AS desc5,t6.amt AS amt6,t6.desc AS desc6,t7.amt AS amt7,t7.desc AS desc7 ,  来自mytable t1  INNER JOIN mytable t2 ON t2.date ='2014-01-01'AND t2.itemid = 10 AND t2.type ='Doors'  INNER JOIN mytable t3 ON t3.date ='2014-01-02'AND t3.itemid = 10 AND t3.type ='Doors'  INNER JOIN mytable t3 ON t3.date ='2014-01-03'AND t3.itemid = 10 AND t4.type ='Doors'  INNER JOIN mytable t3 ON t3.date ='2014-01-04'AND t3.itemid = 10 AND t5.type ='Doors'  INNER JOIN mytable t3 ON t3.date ='2014-01-05'AND t3.itemid = 10 AND t6.type ='Doors'  INNER JOIN mytable t3 ON t3.date ='2014-01-06'AND t3.itemid = 10 AND t7.type ='Doors'  在哪里t1.itemid = 10 AND t1.type ='门'

2 个答案:

答案 0 :(得分:0)

select 
t1.Amount as [Jan 1 Amount],
t1.Description as [Jan 1 Desc.],
t2.Amount as [Jan 2 Amount],
t2.Description as [Jan 2 Desc.],
t3.Amount as [Jan 3 Amount],
t3.Description as [Jan 3 Desc.],
from table t1
inner join table t2 on t2.date='jan 2'
inner join table t3 on t3.date='jan 3'
where t1.date='jan 1'

答案 1 :(得分:0)

尝试使用PIVOT

select 
[Jan 1Amount], [Jan 1Desc], [Jan 2Amount],
[Jan 2Desc], [Jan 3Amount], [Jan 3Desc]
from 
(
  select 
  [date] + column  as column,  value
  from Table1
cross apply
(
select 'Amount', convert(varchar(20),[Amount])  union all
select 'Desc', [Description]
) a (column, value)
) b
pivot
(
 max(value)
 for column in ([Jan 1Amount], [Jan 1Desc], [Jan 2Amount],
             [Jan 2Desc], [Jan 3Amount], [Jan 3Desc])
) pi;

SQL FIDDLE DEMO

如果列未知,则可以使用Dyanmic pivot

DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME([Date] + ' ' +  col) 
                from Table1
                cross apply
                (select 'Amount', convert(varchar(20),[Amount]) 
                 union all
                 select 'Desc', [Description]
                ) c (col, so)
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')


set @query = 'SELECT   ' + @cols + ' 
        from 
        (
            select 
           [date] +'' '' +  col as col, value
           from Table1
        cross apply
         (
          select ''Amount'', convert(varchar(20),[Amount]) 
           union all
           select ''Desc'', [Description]
         ) c (col, value)
        ) x
        pivot 
        (
            max(value)
            for col in (' + @cols + ')
        ) p '


execute sp_executesql @query;

SQL FIDDLE DEMO

相关问题