如果行在其他列中具有相同数据,SQL 查询 CONCAT/list 唯一列数据?
SQL query to CONCAT/list unique column data if rows have identical data in the other columns?
提前致谢。我基本上是在尝试 运行 一个 SQL 查询,以便 StaffID:Name:Floor:Date:Shifts 的结果是 1:1:1:1:Many。
这是我的初始查询和示例结果:
SELECT
ST.STAFFNUM [StaffID],
ST.FULLNAME [Name],
ST.AREA [Floor],
CONVERT(VARCHAR(10), TS.EVENTDATE, 103) [Date],
LEFT(CONVERT(VARCHAR(10), TS.SHIFTSTART, 8), 5) [ShiftStart],
LEFT(CONVERT(VARCHAR(10), TS.SHIFTEND, 8), 5) [ShiftEnd]
FROM
TIMES TS
LEFT JOIN STAFF ST ON TS.STAFFNUM = ST.STAFFNUM
WHERE
TS.EVENTDATE BETWEEN '2021/01/01' AND '2021/01/01'
ORDER BY
ST.AREA,
ST.FULLNAME,
TS.EVENTDATE,
TS.SHIFTSTART
;
StaffID | Name | Floor | Date | ShiftStart | ShiftEnd
==============================================================
1000 | Andrew | 1 | 01/01/2021 | 06:00 | 14:00
1000 | Andrew | 1 | 01/01/2021 | 14:00 | 15:00
8654 | Belinda | 2 | 01/01/2021 | 06:00 | 14:00
9876 | Craig | 3 | 01/01/2021 | 06:00 | 14:00
然后我将 ShiftStart 和 ShiftEnd 列与以下内容结合起来,得到以下结果:
CONCAT(LEFT(CONVERT(VARCHAR(10), TS.SHIFTSTART, 8), 5),'-',LEFT(CONVERT(VARCHAR(10), TS.SHIFTEND, 8), 5)) [Shift]
StaffID | Name | Floor | Date | Shift
====================================================
1000 | Andrew | 1 | 01/01/2021 | 06:00-14:00
1000 | Andrew | 1 | 01/01/2021 | 14:00-15:00
8654 | Belinda | 2 | 01/01/2021 | 06:00-14:00
9876 | Craig | 3 | 01/01/2021 | 06:00-14:00
我想不出接下来要做的是将 Andrew 的班次(以及其他任何人在同一日期和楼层等的多个班次)组合起来,如下所示:
StaffID | Name | Floor | Date | Shifts
=================================================================
1000 | Andrew | 1 | 01/01/2021 | 06:00-14:00, 14:00-15:00
8654 | Belinda | 2 | 01/01/2021 | 06:00-14:00
9876 | Craig | 3 | 01/01/2021 | 06:00-14:00
注意:如果某人被转移到另一个楼层(偶尔),我想将 Shift/s 保留在该楼层独有的单独行中,以便可以拆分楼层数据并通过电子邮件发送给该楼层的经理。
只要行的所有数据都相同,除了 Shift,我想合并这些行并列出 Shifts。
再次感谢!
如上所述,您应该按如下方式使用 String_Agg 函数:
SELECT [StaffID], Max([Name]) As Name, [Floor], [Date], String_Agg([Shift], ',') WITHIN GROUP (ORDER BY [Shift]) As Shifts
FROM (
SELECT
ST.STAFFNUM [StaffID],
ST.FULLNAME [Name],
ST.AREA [Floor],
CONVERT(VARCHAR(10), TS.EVENTDATE, 103) [Date],
CONCAT(LEFT(CONVERT(VARCHAR(10), TS.SHIFTSTART, 8), 5),'-',LEFT(CONVERT(VARCHAR(10), TS.SHIFTEND, 8), 5)) [Shift]
FROM
TIMES TS
LEFT JOIN STAFF ST ON TS.STAFFNUM = ST.STAFFNUM
WHERE
TS.EVENTDATE BETWEEN '2021/01/01' AND '2021/01/01'
ORDER BY
ST.AREA,
ST.FULLNAME,
TS.EVENTDATE,
TS.SHIFTSTART) As T
Group by [StaffID], [Floor], [Date]
对于 Sql Server 2012,您可以尝试使用“CTE”和“FOR XML PATH”。
WITH CTE As
(SELECT
ST.STAFFNUM [StaffID],
ST.FULLNAME [Name],
ST.AREA [Floor],
CONVERT(VARCHAR(10), TS.EVENTDATE, 103) [Date],
CONCAT(LEFT(CONVERT(VARCHAR(10), TS.SHIFTSTART, 8), 5),'-',LEFT(CONVERT(VARCHAR(10), TS.SHIFTEND, 8), 5)) [Shift]
FROM
TIMES TS
LEFT JOIN STAFF ST ON TS.STAFFNUM = ST.STAFFNUM
WHERE
TS.EVENTDATE BETWEEN '2021/01/01' AND '2021/01/01'
ORDER BY
ST.AREA,
ST.FULLNAME,
TS.EVENTDATE,
TS.SHIFTSTART)
SELECT [StaffID], MAX([Name]) AS [Name], [Floor], [Date],
STUFF((SELECT ', ' + [Shift]
FROM CTE
WHERE [StaffID] = T.[StaffID] AND [Floor] = T.[Floor] AND [Date] = T.[Date]
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)'),1,1,'') AS Shifts
FROM CTE AS T
GROUP BY [StaffID], [Floor], [Date]
提前致谢。我基本上是在尝试 运行 一个 SQL 查询,以便 StaffID:Name:Floor:Date:Shifts 的结果是 1:1:1:1:Many。
这是我的初始查询和示例结果:
SELECT
ST.STAFFNUM [StaffID],
ST.FULLNAME [Name],
ST.AREA [Floor],
CONVERT(VARCHAR(10), TS.EVENTDATE, 103) [Date],
LEFT(CONVERT(VARCHAR(10), TS.SHIFTSTART, 8), 5) [ShiftStart],
LEFT(CONVERT(VARCHAR(10), TS.SHIFTEND, 8), 5) [ShiftEnd]
FROM
TIMES TS
LEFT JOIN STAFF ST ON TS.STAFFNUM = ST.STAFFNUM
WHERE
TS.EVENTDATE BETWEEN '2021/01/01' AND '2021/01/01'
ORDER BY
ST.AREA,
ST.FULLNAME,
TS.EVENTDATE,
TS.SHIFTSTART
;
StaffID | Name | Floor | Date | ShiftStart | ShiftEnd
==============================================================
1000 | Andrew | 1 | 01/01/2021 | 06:00 | 14:00
1000 | Andrew | 1 | 01/01/2021 | 14:00 | 15:00
8654 | Belinda | 2 | 01/01/2021 | 06:00 | 14:00
9876 | Craig | 3 | 01/01/2021 | 06:00 | 14:00
然后我将 ShiftStart 和 ShiftEnd 列与以下内容结合起来,得到以下结果:
CONCAT(LEFT(CONVERT(VARCHAR(10), TS.SHIFTSTART, 8), 5),'-',LEFT(CONVERT(VARCHAR(10), TS.SHIFTEND, 8), 5)) [Shift]
StaffID | Name | Floor | Date | Shift
====================================================
1000 | Andrew | 1 | 01/01/2021 | 06:00-14:00
1000 | Andrew | 1 | 01/01/2021 | 14:00-15:00
8654 | Belinda | 2 | 01/01/2021 | 06:00-14:00
9876 | Craig | 3 | 01/01/2021 | 06:00-14:00
我想不出接下来要做的是将 Andrew 的班次(以及其他任何人在同一日期和楼层等的多个班次)组合起来,如下所示:
StaffID | Name | Floor | Date | Shifts
=================================================================
1000 | Andrew | 1 | 01/01/2021 | 06:00-14:00, 14:00-15:00
8654 | Belinda | 2 | 01/01/2021 | 06:00-14:00
9876 | Craig | 3 | 01/01/2021 | 06:00-14:00
注意:如果某人被转移到另一个楼层(偶尔),我想将 Shift/s 保留在该楼层独有的单独行中,以便可以拆分楼层数据并通过电子邮件发送给该楼层的经理。 只要行的所有数据都相同,除了 Shift,我想合并这些行并列出 Shifts。 再次感谢!
如上所述,您应该按如下方式使用 String_Agg 函数:
SELECT [StaffID], Max([Name]) As Name, [Floor], [Date], String_Agg([Shift], ',') WITHIN GROUP (ORDER BY [Shift]) As Shifts
FROM (
SELECT
ST.STAFFNUM [StaffID],
ST.FULLNAME [Name],
ST.AREA [Floor],
CONVERT(VARCHAR(10), TS.EVENTDATE, 103) [Date],
CONCAT(LEFT(CONVERT(VARCHAR(10), TS.SHIFTSTART, 8), 5),'-',LEFT(CONVERT(VARCHAR(10), TS.SHIFTEND, 8), 5)) [Shift]
FROM
TIMES TS
LEFT JOIN STAFF ST ON TS.STAFFNUM = ST.STAFFNUM
WHERE
TS.EVENTDATE BETWEEN '2021/01/01' AND '2021/01/01'
ORDER BY
ST.AREA,
ST.FULLNAME,
TS.EVENTDATE,
TS.SHIFTSTART) As T
Group by [StaffID], [Floor], [Date]
对于 Sql Server 2012,您可以尝试使用“CTE”和“FOR XML PATH”。
WITH CTE As
(SELECT
ST.STAFFNUM [StaffID],
ST.FULLNAME [Name],
ST.AREA [Floor],
CONVERT(VARCHAR(10), TS.EVENTDATE, 103) [Date],
CONCAT(LEFT(CONVERT(VARCHAR(10), TS.SHIFTSTART, 8), 5),'-',LEFT(CONVERT(VARCHAR(10), TS.SHIFTEND, 8), 5)) [Shift]
FROM
TIMES TS
LEFT JOIN STAFF ST ON TS.STAFFNUM = ST.STAFFNUM
WHERE
TS.EVENTDATE BETWEEN '2021/01/01' AND '2021/01/01'
ORDER BY
ST.AREA,
ST.FULLNAME,
TS.EVENTDATE,
TS.SHIFTSTART)
SELECT [StaffID], MAX([Name]) AS [Name], [Floor], [Date],
STUFF((SELECT ', ' + [Shift]
FROM CTE
WHERE [StaffID] = T.[StaffID] AND [Floor] = T.[Floor] AND [Date] = T.[Date]
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)'),1,1,'') AS Shifts
FROM CTE AS T
GROUP BY [StaffID], [Floor], [Date]