如何将列值转换为列?

时间:2012-09-05 18:02:35

标签: sql-server pivot

我浏览了Stackoverflow上的很多SQL Pivot示例,在联机丛书和谷歌中,我仍然无法弄清楚如何执行(我会称之为)一个简单的数据透视操作。

Example 1

示例数据:

Name     Class       Score
=======  ==========  ======
Nick     Chinese     80 
Nick     English     70 
Nick     Biology     85 
Nick     Maths       85
Kent     Chinese     80 
Kent     Maths       90 
Kent     English     70 
Kent     Biology     85 

所需输出1 - 按类转动,按名称汇总

Name     Chinese     English   Biology  Maths
=======  ==========  ========  =======  ======
Nick     80          70        85       85
Kent     80          70        85       90

注意:

  

在我脑海中,我想象的语法是:

SELECT Score FROM Scores
GROUP BY Name
PIVOT BY Class

期望输出2 - 按类分类,汇总分数

Name     Chinese     English   Biology  Maths
=======  ==========  ========  =======  ======
70                   Nick
70                   Kent
80       Nick        
80       Kent             
85                             Nick     Nick
85                             Kent
90                                      Kent

注意:

  

在我脑海中,我想象的语法是:

SELECT Name FROM Scores
GROUP BY Score
PIVOT BY Class

期望输出3 - 按分数转数,按名称汇总

Name     70          80        85       90
=======  ==========  ========  =======  =====
Nick     English     Chinese   Biology  
Nick     English     Chinese   Maths
Kent     English     Chinese   Biology  Maths

注意:

  

在我脑海中,我想象的语法是:

SELECT Class FROM Scores
GROUP BY Name
PIVOT BY Score

期望输出4 - 按分数转数,按类别汇总

Class    70          80        85       90
=======  ==========  ========  =======  =====
Chinese              Nick
Chinese              Kent
English  Nick
English  Kent
Biology                        Nick
Biology                        Kent
Maths                          Nick     Kent
  

在我脑海中,我想象的语法是:

SELECT Name FROM Scores
GROUP BY Class 
PIVOT BY Score

所需的输出5 - 按名称进行透视,按类

聚合
Class    Nick  Kent
=======  ====  ====
Chinese  80    80
English  70    70
Biology  85    85
Maths    85    90
  

在我脑海中,我想象的语法是:

SELECT Score FROM Scores
GROUP BY Class
PIVOT BY Name

期望输出6 - 按名称转动,按分数汇总

Score  Nick     Kent
=====  =======  =======
70     English  English
80     Chinese  Chinese
85     Biology  Biology
85     Maths    Biology
90              Maths
  

在我脑海中,我想象的语法是:

SELECT Class FROM Scores
GROUP BY Score
PIVOT BY Name

注意:我不希望能够执行所有这些支点的单个查询。我正在使用示例数据和示例枢轴,因此请使用我可能想要执行的枢轴的示例。

另一个示例集

另一个例子可能是解析用户登录域的日志:

LoginDate          Username  MachineName
=================  ========  ===========
20120901 8:49:22   iboyd     obsidian
20120901 9:10:19   nbach     president
20120901 13:07:18  nback     nichpc
20120902 8:58:38   iboyd     obsidian
20120202 9:14:44   nbach     president
20120902 18:34:43  iboyd     harpax
20120903 8:57:13   iboyd     obsidian
20120904 20:03:55  iboyd     harpax

所需输出7 - 按日期部分透过LoginDate进行透视,按用户名聚合:

Username  20120901   20120902  20120903  20120914
========  =========  ========  ========  ========
iboyd     obsidian   obsidian  obsidian  harpax
iboyd     obsidian   harpax    obsidian  harpax
nbach     president  president
nback     nichpc     president
  

在我脑海中,我想象的语法是:

SELECT MachineName FROM Logins
GROUP BY Username
PIVOT BY CONVERT(varchar(50), LoginDate, 112) --yyyymmdd format
     

或者也许:

SELECT MachineName FROM Logins
GROUP BY Username
PIVOT BY CAST(LoginDate AS DATE)

我似乎无法将PIVOT语法包裹起来;为了告诉SQL Server哪些列值应该成为列,以及聚合发生的列值。

每个人似乎都想对列进行硬编码,或者调用一些XML查询。我只是想做一个支点!


另见


真实问题 TM

我今天要解决的真正问题是“business”给我的截图模型:

enter image description here

如果SQL Server语法对我来说非常明显,那么写一个相当明显的查询:

SELECT 
    JobName, ShiftName, 
    Firstname+' '+Lastname+' - '+BankCode
FROM Transactions
GROUP BY JobName, ShiftName
PIVOT BY TransactionDate

1 个答案:

答案 0 :(得分:4)

将pivot操作符视为替换您的组。以下是您的示例#1和3的示例:

SELECT name, [Chinese], [English], [Biology], [Maths]
FROM scores s
PIVOT (
    SUM(score) 
    FOR Class IN ([Chinese], [English], [Biology], [Maths])
) p

SELECT name, [70], [80], [85], [90]
FROM scores s
PIVOT (
    MAX(class) 
    FOR score IN ([70], [80], [85], [90])
) p