如何在Sql server查询中透视两列?

时间:2013-10-10 05:56:09

标签: sql sql-server

请帮我解决我的问题。 我正在使用SQL Server 2005,我完成了一个查询,然后我得到了如下数据

Name       Month        Year      Qty       Unique Number
A          October      2013      30000     4986975
B          October      2013      4378      2439257
C          October      2013      14575     8378872
D          October      2013      2400      1756443
A          January      2014      20000     1752369
D          January      2014       1500     1236978
A          February     2014       2000     1897606

但我想要这样的数据如下

Name            october-2013             January-2014            February-2014
                Qty     Number           Qty     Number          Qty      Number      
A              30000    4986975         20000    1752369         2000     1897606
B              4378     2439257           0         0             0         0
C              14575    8378872           0         0             0         0
D               2400    1756443          1500    1236978          0         0

所以请帮助我获取这样的数据。

感谢名单

3 个答案:

答案 0 :(得分:0)

create table table1 (Name varchar(20),[Month] varchar(10), [Year] varchar(10) , qty int, [Unique_Number] int);
insert into table1 values 
('A','October','2013',30000,4986975),
('B','October','2013',4378,2439257),
('C','October','2013',14575,8378872),
('D','October','2013',2400,1756443),
('A','January','2014',20000,175236),
('D','January','2014', 1500,1236978),
('A','February','2014', 2000,1897606);


select tblQty.Name,[October-2013-QTY],[October-2013-NUM],[January-2014-QTY],[January-2014-NUM],[February-2014-QTY],[February-2014-NUM] from 
(select Name,
        isnull([October-2013],0) as[October-2013-QTY] ,
        isnull([January-2014],0) as[January-2014-QTY],
        isnull([February-2014],0) as [February-2014-QTY]
from 
(select Name , [Month]+'-'+[Year] as SpreadCol , qty
from table1 ) as D
pivot (sum(qty)
       for SpreadCol
       IN ([October-2013],[January-2014],[February-2014]))as Pivot1) tblQty
inner join
(
select Name,
       isnull([October-2013],0) as[October-2013-NUM] ,
       isnull([January-2014],0) as[January-2014-NUM],
       isnull([February-2014],0) as [February-2014-NUM] 
from 
(select Name , [Month]+'-'+[Year] as SpreadCol , Unique_Number 
from table1 ) as D
pivot (MAx(Unique_Number)
       for SpreadCol
       IN ([October-2013],[January-2014],[February-2014]))as Pivot2 ) tblNum

on tblNum.Name = tblQty.Name ;

[编辑:带有所需排序的动态查询]:

DECLARE @columns NVARCHAR(MAX)
       ,@columnsQTY NVARCHAR(MAX)
       ,@columnsNUM NVARCHAR(MAX)
       ,@columnsFNL NVARCHAR(MAX)
       ,@sql NVARCHAR(MAX);

SET @columns = N'';
--Get column names for entire pivoting
SELECT @columns += N', ' + QUOTENAME(SpreadCol)
  FROM (select distinct [Month]+'-'+[Year] as SpreadCol 
        from table1
       ) AS T;  
PRINT @columns;

--Get column names for Pivot1
SET @columnsQTY = N'';
SELECT @columnsQTY += N', ISNULL(' + QUOTENAME(SpreadCol) + ',0) AS [' + SpreadCol + '-QTY]'
  FROM (select distinct [Month]+'-'+[Year] as SpreadCol
        from table1
       ) AS T
 ;
PRINT @columnsQTY;

--Get column names for Pivot2
SET @columnsNUM = N'';
SELECT @columnsNUM += N', ISNULL(' + QUOTENAME(SpreadCol) + ',0) AS [' + SpreadCol + '-NUM]'
  FROM (select distinct [Month]+'-'+[Year] as SpreadCol
        from table1
       ) AS T
 ; 
PRINT @columnsNUM;

--Get final list of columns:
  SET @columnsFNL = N'';
  SELECT @columnsFNL += N', [' + SpreadCol + '-QTY], [' + SpreadCol + '-NUM] '
  FROM (select distinct [Month]+'-'+[Year] as SpreadCol,
        DATEPART(MM, Upper([Month]) + ' 01 1990') as [MonthNum] ,[Year]
        from table1
       ) AS T
    order by T.[Year] asc , T.[MonthNum] desc; -- change ordering of columns here
PRINT @columnsFNL;

SET @sql = N'
select tblQty.Name, ' + STUFF(@columnsFNL, 1, 2, '') + ' from 
'
+
'
( SELECT Name, ' + STUFF(@columnsQTY, 1, 2, '') + '
FROM
(select Name , [Month]+''-''+[Year] as SpreadCol , qty
from table1 ) as D
PIVOT
(
  sum(qty) FOR SpreadCol IN ('
  + STUFF(REPLACE(@columns, ', [', ',['), 1, 1, '')
  + ')
) AS Pivot1 ) tblQty
inner join
'
+
 '
( SELECT Name, ' + STUFF(@columnsNUM, 1, 2, '') + '
FROM
(select Name , [Month]+''-''+[Year] as SpreadCol , Unique_Number
from table1 ) as D
PIVOT
(
  MAx(Unique_Number) FOR SpreadCol IN ('
  + STUFF(REPLACE(@columns, ', [', ',['), 1, 1, '')
  + ')
) as Pivot2 ) tblNum
on tblNum.Name = tblQty.Name ;
'

;

PRINT @sql;
EXEC sp_executesql @sql;

希望这有帮助!!!

答案 1 :(得分:0)

我使用stuff来获取列名,然后使用这些列来获得结果

然后我使用2个枢轴来获得Qty和Unique_Number的结果,然后加入两个结果以获得所需的结果

select * into #tbl from (
Select 'A' NAME,'October' Month ,2013 Year ,30000 QTY, 4986975 Unique_NUmber
UNION SELECT 'B','October',      2013,      4378 ,     2439257
UNION SELECT 'C','October',      2013,      14575,     8378872
UNION SELECT 'D','October',      2013,      2400 ,     1756443
UNION SELECT 'A','January',      2014,      20000,     1752369
UNION SELECT 'D','January',      2014,       1500,     1236978
UNION SELECT 'A','February',     2014,       2000,     1897606
) A

Declare @cols1 as nvarchar(max)

Declare @cols2 as nvarchar(max)


set @cols1 = STUFF((        
        select col from (       
        select distinct ',['+MONTH+'-'+CAST(YEAR as varchar)+'-Qty]' col, DATEPART(MM,'01 '+Month + ' ' + CAST(YEAR as varchar)) MonthNumber ,year
        from #tbl group by year,DATEPART(MM,'01 '+Month + ' ' + CAST(YEAR as varchar)),',['+MONTH+'-'+CAST(YEAR as varchar)+'-Qty]'
                ) A
        for XML PATH(''), TYPE).value('.','NVARCHAR(MAX)') ,1,1,'')
set @cols2 = STUFF((        
        select col from (       
        select distinct ',['+MONTH+'-'+CAST(YEAR as varchar)+'-UN]' col, DATEPART(MM,'01 '+Month + ' ' + CAST(YEAR as varchar)) MonthNumber ,year
        from #tbl group by year,DATEPART(MM,'01 '+Month + ' ' + CAST(YEAR as varchar)),',['+MONTH+'-'+CAST(YEAR as varchar)+'-UN]'
                ) A
        for XML PATH(''), TYPE).value('.','NVARCHAR(MAX)') ,1,1,'')
--print @cols1

--select * from #tbl

declare @query as Nvarchar(max)

set @query='select A.*, B.* from 
            (select NAME, MONTH+''-''+CAST(YEAR as varchar)+''-QTY''MonthYear, QTY
            from #tbl) as A
            PIVOT
            (
            SUM(QTY)
            FOR MonthYear IN ('+ @cols1 +')
            ) AS A
            left join 
            (
            select * from 
            (select NAME, MONTH+''-''+CAST(YEAR as varchar)+''-UN''MonthYear, Unique_NUmber
            from #tbl) as A
            PIVOT
            (
            SUM(Unique_NUmber)
            FOR MonthYear IN ('+ @cols2 +')
            ) AS P ) B on A.Name=B.NAME
            '


execute(@query)

drop table #tbl

希望这会有所帮助:D

答案 2 :(得分:0)

Microsoft SQL Server具有包含的透视功能。

使用那个更容易。

请看一下手册。 Using PIVOT and UNPIVOT

它很好地解释了包括一些样本。