SQL - 将行转置为列

时间:2017-10-07 01:48:59

标签: sql sql-server tsql

我正在努力实现以下目标:

鉴于:

Name | Color   | Value |
------------------------
John |  Red    |   2   |
------------------------
John |  Blue   |   5   |
------------------------
John | Yellow  |   10  | 
------------------------

预期:

Name |  Red  |  Blue  |  Yellow  |
----------------------------------
John |   2   |    5   |    10    |
----------------------------------

基本上我希望做的是将颜色列设为单个列,其值为行值。但是有一个问题,你只能使用以下SQL函数:

聚集体

Avg(),Count(),Max(),Min(),Sum(),Round()

算术运算符

  • (add), - (减法),/(除),%(modulo),*(乘法)

比较运算符

=(等于),> (大于),< (小于),> =(大于或等于),< =(小于或等于),<> (不等于),!=(不等于),!< (不小于),!> (不大于)

逻辑运算符

而且,或者,不,在,在,在,像,任何,所有,有些,存在

功能

Case,Cast,Convert,Current_timestamp,DateAdd,DateDiff,DateName,DatePart,GetDate(),IsDate,Left,Len,Lower,Ltrim,Replace,Replicate,Reverse,Right,Rtrim,Space,Str,Substring,SUBSTRING (表达式,开始,长度),Sysdatetime,Upper

我能够让它将颜色显示为列标题并返回其值。但是,这会导致返回其他颜色值,如下所示:

Name |   Red   |
----------------
John |    2    |
----------------
John |         |
----------------
John |         |
----------------

我知道其他颜色值占据了其他行,因为我添加了一个带有颜色名称的附加列。我使用的公式如下:

CASE Color WHEN 'Red' THEN Value END

我知道我错过了一个约束,但我不知道我错过了什么。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:4)

如果我理解,您只是错过了条件聚合和分组依据

示例

Select Name
      ,Red   = sum(case when Color='Red'    then Value end)
      ,Blue  = sum(case when Color='Blue'   then Value end)
      ,Yellow= sum(case when Color='Yellow' then Value end)
 From  YourTable
 Group By Name

<强>返回

Name    Red  Blue   Yellow
John    2    5      10

答案 1 :(得分:1)

&#34;相关子查询&#34;?

SELECT ot.NAME, 
(SELECT SUM(t1.RED) FROM xTable as t1 where t1.NAME = ot.NAME) as RED,
(SELECT SUM(t1.BLUE) FROM xTable as t1 where t1.NAME = ot.NAME) as BLUE,
(SELECT SUM(t1.YELLOW) FROM xTable as t1 where t1.NAME = ot.NAME) as YELLOW
FROM xTable as ot

答案 2 :(得分:1)

延迟更新。如果是2012+,也许你可以使用窗口函数。

没有GROUP BY,但有DISTINCT

示例

Select Distinct
       Name
      ,Red   = sum(case when Color='Red'    then Value end) over (Partition By Name)
      ,Blue  = sum(case when Color='Blue'   then Value end) over (Partition By Name)
      ,Yellow= sum(case when Color='Yellow' then Value end) over (Partition By Name)
 From  @YourTable