繁体   English   中英

SQL Server如何在没有PIVOT或UNPIVOT或聚合的情况下将行转置为列[重复]

[英]SQL Server How To Transpose Rows To Columns, without PIVOT or UNPIVOT or Aggregation [duplicate]

这个问题已经在这里有了答案:

编辑1:两种解决方案和DUPE链接都起作用,但是它们都没有保留我想要的列顺序。 所有解决方案均按字母顺序对结果列名称进行排序。 如果有人对此有解决方案,请发表评论。

编辑2: @taryn已在注释中发布了此SQL 提琴 ,该列也进行了排序:)


我已经看到了无数这样的答案,但是这些都不是我想要实现的目标。 几乎所有人都涉及进行汇总或分组。 因此,在急于将其标记为DUPE之前,请先完整阅读问题。

我要做的就是将行转置为列,原始结果集的列名将成为新结果集的第一列的行值。

这是我的数据的样子,以及我想如何将其转换/转置。

在此处输入图片说明

我已经对其进行了颜色编码,因此您可以快速清晰地理解这一点。

在excel中,我可以通过选择第一个表,将其复制,然后右键单击并将其粘贴为“ 选择性粘贴”并选中“ 转置”复选框来实现。

我尝试了PIVOTUNPIVOT ,但似乎都没有给我我想要的东西。 我可能没有正确使用它,但是我花了很多时间来解决这个问题。

我已经使用源表,示例数据和此处的预期值创建了一个SQL Fiddle,因此您必须从=> http://www.sqlfiddle.com/#!18/56afd/10开始

这也是内联粘贴的代码。

IF OBJECT_ID ('dbo.Players') IS NOT NULL
    DROP TABLE dbo.Players;

CREATE TABLE dbo.Players
(
      PlayerID INT
    , Win INT
    , Defeat INT
    , StandOff INT
    , CONSTRAINT PK_Players PRIMARY KEY CLUSTERED (PlayerID) ON [PRIMARY]
);
INSERT INTO dbo.Players (PlayerID, Win, Defeat, StandOff)
VALUES
    (1, 7,  6,  9),
    (2, 12, 5,  0),
    (3, 3,  11, 1);

这是预期的输出

SELECT * FROM dbo.Players;

-- Need to Transpose above results, into the following.

-- -------------------------------------------------------------------
-- |    Stat_Type    |    Player_1    |    Player_2    |    Player_3  |
-- -------------------------------------------------------------------
-- |    Win          |       7        |       12       |      3       |
-- -------------------------------------------------------------------
-- |    Defeat       |       6        |       5        |      11      |
-- -------------------------------------------------------------------
-- |    StandOff     |       9        |       0        |      1       |
-- -------------------------------------------------------------------

-- Column Names become Row values for 1st column
-- PlayerId becomes column names

在SQL Server中,我会这样做:

select v.outcome,
       max(case when v.playerId = 1 then val end) as playerId_1,
       max(case when v.playerId = 2 then val end) as playerId_2,
       max(case when v.playerId = 3 then val end) as playerId_3
from players cross apply
     (values (playerId, win, 'win', 1),
             (playerId, defeat, 'defeat', 2),
             (playerId, standoff, 'standoff', 3)
     ) v(playerId, val, outcome, ordering)
group by v.outcome
order by max(ordering);

是SQL Fiddle。

您应该能够使用pivot / unpivot执行相同的操作。 如果您不知道参与者或结果的完整列表,那么您将需要动态SQL。

更新: 这是带有自定义排序顺序 SQL Fiddle。 信用: @Taryn

使用UNPIVOT/PIVOT

WITH unpiv AS (
  SELECT PlayerId, col, value
  FROM dbo.Players
  UNPIVOT (VALUE FOR col IN (Win, Defeat, StandOff)) unpiv
)
SELECT col AS Stat_Type, [1] AS Player1, [2] AS Player2, [3] AS Player3
FROM unpiv
PIVOT (MAX(value) FOR PlayerId IN ([1], [2], [3])) piv
ORDER BY CASE col WHEN 'Win' THEN 1 WHEN 'Defeat' THEN 2 ELSE 3 END;

DBFiddle演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM