将行转置为不聚合的列

Posted

技术标签:

【中文标题】将行转置为不聚合的列【英文标题】:Transpose rows to columns without aggragation 【发布时间】:2017-05-19 10:30:14 【问题描述】:

我想根据 RuleID 和 Dname 将行转置为列。以下是示例数据。请帮我实现它

CREATE TABLE [dbo].[Table1](
[RuleID] [nvarchar](10) NULL,
[DateTime1] [datetime] NULL,
[DName] [nvarchar](30) NULL
) ON [PRIMARY]

INSERT [dbo].Table1 ([RuleID], [DateTime1], [DName]) VALUES (N'DBRS', CAST(N'2017-03-28T12:22:04.000' AS DateTime), N'DB1')
INSERT [dbo].Table1 ([RuleID], [DateTime1], [DName]) VALUES (N'DBRK', CAST(N'2017-03-28T12:22:04.260' AS DateTime), N'DB1')
INSERT [dbo].Table1 ([RuleID], [DateTime1], [DName]) VALUES (N'DBRE', CAST(N'2017-03-28T12:22:09.000' AS DateTime), N'DB1')
INSERT [dbo].Table1 ([RuleID], [DateTime1], [DName]) VALUES (N'DBRK', CAST(N'2017-04-04T08:33:15.870' AS DateTime), N'DB2')
INSERT [dbo].Table1 ([RuleID], [DateTime1], [DName]) VALUES (N'DBRE', CAST(N'2017-04-04T08:33:31.000' AS DateTime), N'DB2')
INSERT [dbo].Table1 ([RuleID], [DateTime1], [DName]) VALUES (N'DBRK', CAST(N'2017-04-04T09:14:30.503' AS DateTime), N'DB2')
INSERT [dbo].Table1 ([RuleID], [DateTime1], [DName]) VALUES (N'DBRS', CAST(N'2017-04-04T09:14:31.000' AS DateTime), N'DB2')
INSERT [dbo].Table1 ([RuleID], [DateTime1], [DName]) VALUES (N'DBRE', CAST(N'2017-04-04T09:44:33.000' AS DateTime), N'DB2')

期望的输出:

SELECT 'DB1' As DName,'2017-03-28 12:22:04.260'AS BRKIndicated ,'2017-03-28 12:22:04.000' As BRKStart,'2017-03-28 12:22:09.000' AS BRKEnd
UNION
SELECT 'DB2'As DName,'2017-04-04 08:33:15.870'AS BRKIndicated,NULL As BRKStart,'2017-04-04 08:33:31.000'AS BRKEnd
UNION
SELECT 'DB2'As DName,'2017-04-04 09:14:30.503'AS BRKIndicated,'2017-04-04 09:14:31.000' As BRKStart,'2017-04-04 09:44:33.000'AS BRKEnd

【问题讨论】:

【参考方案1】:

使用 PIVOT 表:

SELECT *
FROM 
(
   SELECT * 
   FROM Table1
) A 
PIVOT
(
  MAX(DateTime1) FOR RuleID IN ([DBRS],[DBRK],[DBRE])
)pvt 

【讨论】:

如果我使用 Max(DateTime1),我会错过第二行【参考方案2】:

使用自联接

select D1.DName, D1.DateTime1 as DBRS, D2.DateTime1 as DBRK, D3.DateTime1 as DBRE
from Table1 D1
inner join Table1 D2
  on D1.DName = D2.DName
  and D2.RuleID = 'DBRK'
inner join Table1 D3
  on D1.DName = D3.DName
  and D3.RuleID = 'DBRE'
where D1.RuleID = 'DBRS'

如果可能缺少其中一个值,请改用LEFT JOIN

【讨论】:

这给了我重复项 @user2545157 您的数据中有重复项...您如何确定每个“DB2”项属于哪一行? DBRK 是中断指示,DBRS 是 Breakstart,DBRE 是 BreakEnd..所有这些都针对每个 Dname 设置一个集合..如果其中任何一个缺失,则应将其更新为 null.. 检查您的样本数据,它与您的预期输出不匹配。如果有更多条件,请将它们应用于联接,但这是您需要的解决方案。

以上是关于将行转置为不聚合的列的主要内容,如果未能解决你的问题,请参考以下文章

将行转置为 BigQuery 中的列(数据透视实现)[重复]

将行转置为具有条件的列[重复]

如何从列转置到行?

将行转置为单列

SQL 将行转置为列

Tsql 将行转置为列,按列分组