问题描述
我有一个 datetime
列,其中包含同一日期的几个小时。我想在不重复的情况下在一列中设置日期,在另一列中设置连接的小时数。
表结构为:
USERID CHECKTIME
-----------------------------
89 02/02/2021 05:06:07
89 02/02/2021 09:07:08
89 02/02/2021 12:15:20
89 03/02/2021 10:11:12
我正在寻找的输出是:
DATE HOURS
------------------------------------------
02/02/2021 05:06:07,09:07:08,12:15:20
03/02/2021 10:11:12
我尝试了以下查询,但是所有行的结果小时数都相同。我知道这是因为我将值指定为文字,但是,我找不到如何对查询进行编码,因此,每个不同日期的小时数都会连接起来:
SELECT disTINCT
FORMAT(CHECKTIME,'dd/MM/yyyy') AS DATE,STUFF((SELECT ',' + FORMAT(CHECKTIME,'HH:mm:ss')
FROM dbo.CHECKINOUT_PD
WHERE FORMAT(CHECKTIME,'dd/MM/yyyy') = '02/02/2021'
AND USERID = 89
FOR XML PATH ('')),1,2,'') AS HOURS
FROM
dbo.CHECKINOUT_PD
WHERE
FORMAT(CHECKTIME,'MM/yyyy') = '02/2021'
AND USERID = 89
感谢您提供的任何帮助。
先谢谢你!
解决方法
您只需要将内部查询与外部查询相关联。
请注意,format
非常昂贵,应尽可能避免使用 - 特别是在 where
子句中使用时 - 在本机数据类型而不是字符串中进行比较要好得多。
declare @Test table (UserId int,CheckTime datetime2(0))
insert into @Test (UserId,CheckTime)
values
(89,'02/02/2021 05:06:07'),(89,'02/02/2021 09:07:08'),'02/02/2021 12:15:20'),'03/02/2021 10:11:12');
SELECT CAST(CHECKTIME AS date) AS [DATE],STUFF((
SELECT ',' + FORMAT(T2.CHECKTIME,'HH:mm:ss')
FROM @Test T2
WHERE CAST(T2.CHECKTIME AS date) = CAST(T1.CHECKTIME AS date)
AND T1.USERID = T2.USERID
FOR XML PATH ('')
),1,2,'') AS [HOURS]
FROM @Test T1
WHERE T1.USERID = 89
GROUP BY T1.USERID,CAST(T1.CHECKTIME AS date);
您可以使用 string_agg(如果使用 SQL Server 2017+)
SELECT CAST(CHECKTIME AS date) AS [DATE],STRING_AGG(FORMAT(T1.CHECKTIME,'HH:mm:ss'),',') WITHIN GROUP (order by T1.CHECKTIME asc) [HOURS]
FROM @Test T1
WHERE T1.USERID = 89
GROUP BY T1.USERID,CAST(T1.CHECKTIME AS date);
注意:如果您将示例数据的 DDL+DML 添加到以后的问题中,它会更容易获得帮助。