SQL Server:分组和合并列

时间:2018-08-24 21:53:52

标签: sql sql-server

--Create/Populate [#Feedback]:
if object_id('tempdb..[#Feedback]','U') is not null 
    drop table [#Feedback]
go

create table [#Feedback]
(
     [feedbackid] int,
     [feedbackgroup] varchar(50),
     [feedbackdatetime] datetime,
     [feedbackresult] varchar(max),
     [feedbackdataelement] varchar(50)
)
go

set nocount on
insert [#Feedback] select 1, 'A001', '2018-08-24 08:00:00', 'true', 'ArrivedLate'
insert [#Feedback] select 2, 'A001', '2018-08-24 08:00:00', 'false', 'LeftEarly'
insert [#Feedback] select 3, 'A001', '2018-08-24 08:00:00', 'false', 'Unprepared'
insert [#Feedback] select 4, 'A001', '2018-08-24 08:00:00', 'Arrived 5 minutes late', 'Comments'
insert [#Feedback] select 5, 'A056', '2018-08-24 09:14:00', 'false', 'ArrivedLate'
insert [#Feedback] select 6, 'A056', '2018-08-24 09:14:00', 'false', 'LeftEarly'
insert [#Feedback] select 7, 'A056', '2018-08-24 09:14:00', 'true', 'Unprepared'
insert [#Feedback] select 8, 'A056', '2018-08-24 09:14:00', 'Did not bring laptop', 'Comments'
insert [#Feedback] select 9, 'B251', '2018-08-24 12:28:00', 'true', 'ArrivedLate'
insert [#Feedback] select 10, 'B251', '2018-08-24 12:28:00', 'true', 'Left Early'
insert [#Feedback] select 11, 'B251', '2018-08-24 12:28:00', 'true', 'Unprepared'
insert [#Feedback] select 12, 'B251', '2018-08-24 12:28:00', 'Showed up an hour late and had not showered, left at noon', 'Comments'
go
select * from [#Feedback]

我正在使用一个看起来像这样的表。我正在尝试对数据进行一些格式化。

理想情况下,这就是我想要的输出。

Group   DateTime            Feedback                                Comments
A001    2018-08-24 08:00:00 Arrived Late                            Arrived 5 minutes late
A056    2018-08-24 09:14:00 Unprepared                              Did not bring laptop
B251    2018-08-24 12:28:00 Arrived Late, Left Early, Unprepared    Showed up an hour late and had not showered, left at noon

我不确定该怎么做。我需要将所有feedbackgroup ID分组在一起,然后需要检查feedbackresult是否为真,如果是,则在列中列出。如果有多个是对的,那么我需要在单列中列出它们。最后,我需要将“评论”放在自己的列中。

理想情况下,我还希望新的“ Feedback”(反馈)列具有更好的格式措辞(“ Arrived Late”而不是“ ArrivedLate”)。

2 个答案:

答案 0 :(得分:2)

如果您使用的是SQL Server(从2017年开始),则可以尝试使用STRING_AGG

否则,请尝试此。如果一个ID允许有多个注释,则需要相应地更改“注释”列(如“反馈”列)。我忽略了字格式,因为它确实很模糊。

SELECT DISTINCT 
  f1.[feedbackgroup] as Group, 
  max([feedbackdatetime]) as Datetime,
  Stuff((SELECT ', ' + f2.[feedbackdataelement] 
       FROM [#feedback] AS f2 
       WHERE (f2.[feedbackresult] = 'true' AND f2.[feedbackgroup] = f1.[feedbackgroup]) 
       FOR xml path(''), type).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '') 
  AS Feedback, 
  (SELECT [feedbackresult] FROM [#feedback] AS f3 
   WHERE  f3.[feedbackdataelement] = 'Comments' AND f3.feedbackgroup = f1.feedbackgroup) 
   AS Comments 
FROM   [#feedback] AS f1 
GROUP  BY f1.[feedbackgroup] 

答案 1 :(得分:2)

一般来说,您希望CASE返回一个非空或空字符串,具体取决于[feedbackdataelement][feedbackresult]max()的值,可能还取决于GROUP BY [feedbackgroup]的值

SELECT [feedbackgroup] [group],
       max([feedbackdatetime]) [datetime],
       stuff(concat(max(CASE
                          WHEN [feedbackdataelement] = 'ArrivedLate'
                               AND [feedbackresult] = 'true' THEN
                            ', Arrived Late'
                          ELSE
                            ''
                        END),
                    max(CASE
                          WHEN [feedbackdataelement] = 'LeftEarly'
                               AND [feedbackresult] = 'true' THEN
                            ', Left Early'
                          ELSE
                            ''
                        END),
                    max(CASE
                          WHEN [feedbackdataelement] = 'Unprepared'
                               AND [feedbackresult] = 'true' THEN
                            ', Unprepared'
                          ELSE
                            ''
                        END)),
             1,
             2,
             '') [feedback],
       max(CASE [feedbackdataelement]
             WHEN 'Comments' THEN
               [feedbackresult]
             ELSE
               ''
           END) [comments]
       FROM [feedback]
       GROUP BY [feedbackgroup];