Sql 选择“按日期将同一列分组到不同列”
我有一个如下所示的登录表:Sql 选择“按日期将同一列分组到不同列”,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一个如下所示的登录表: Created | Action 20/01/2016 08:00:00 AM login 20/01/2016 10:05:10 AM logout 20/01/2016 12:00:00 PM login 20/01/2016 04:12:22 PM logout 21/01/2016 08:00:50 AM login 21/01/2016 09:44:42 AM login 21/01/201
Created | Action
20/01/2016 08:00:00 AM login
20/01/2016 10:05:10 AM logout
20/01/2016 12:00:00 PM login
20/01/2016 04:12:22 PM logout
21/01/2016 08:00:50 AM login
21/01/2016 09:44:42 AM login
21/01/2016 10:44:42 AM login
21/01/2016 04:00:42 PM logout
Created | Login | Logout
20/01/2016 08:00:00 AM 04:12:22 PM
21/01/2016 08:00:50 PM 04:00:42 PM
SELECT
CONVERT(VARCHAR(10),li.Created,10) [Date],
CONVERT(VARCHAR(8),MAX(li.Created),8) [Login],
CONVERT(VARCHAR(8),MAX(lo.Created),8) [Logout]
From Logins li
Left Join Logins lo on lo.[Action] = 'logout'
GROUP BY CAST(li.Created AS DATE)
我需要选择一个如下所示的结果集:
Created | Action
20/01/2016 08:00:00 AM login
20/01/2016 10:05:10 AM logout
20/01/2016 12:00:00 PM login
20/01/2016 04:12:22 PM logout
21/01/2016 08:00:50 AM login
21/01/2016 09:44:42 AM login
21/01/2016 10:44:42 AM login
21/01/2016 04:00:42 PM logout
Created | Login | Logout
20/01/2016 08:00:00 AM 04:12:22 PM
21/01/2016 08:00:50 PM 04:00:42 PM
SELECT
CONVERT(VARCHAR(10),li.Created,10) [Date],
CONVERT(VARCHAR(8),MAX(li.Created),8) [Login],
CONVERT(VARCHAR(8),MAX(lo.Created),8) [Logout]
From Logins li
Left Join Logins lo on lo.[Action] = 'logout'
GROUP BY CAST(li.Created AS DATE)
以下是我尝试过的:
SELECT
CONVERT(VARCHAR(10),li.Created,10) [Date],
CONVERT(VARCHAR(8),MAX(li.Created),8) [Login],
CONVERT(VARCHAR(8),MAX(lo.Created),8) [Logout]
FROM Logins li
LEFT JOIN Logins lo ON lo.[Action] = 'logout'
GROUP BY li.Created
但结果不是按日期分组的
正确的方法是什么?您可以这样尝试:
Created | Action
20/01/2016 08:00:00 AM login
20/01/2016 10:05:10 AM logout
20/01/2016 12:00:00 PM login
20/01/2016 04:12:22 PM logout
21/01/2016 08:00:50 AM login
21/01/2016 09:44:42 AM login
21/01/2016 10:44:42 AM login
21/01/2016 04:00:42 PM logout
Created | Login | Logout
20/01/2016 08:00:00 AM 04:12:22 PM
21/01/2016 08:00:50 PM 04:00:42 PM
SELECT
CONVERT(VARCHAR(10),li.Created,10) [Date],
CONVERT(VARCHAR(8),MAX(li.Created),8) [Login],
CONVERT(VARCHAR(8),MAX(lo.Created),8) [Logout]
From Logins li
Left Join Logins lo on lo.[Action] = 'logout'
GROUP BY CAST(li.Created AS DATE)
也就是说,你只需要按日期分组,而不是同时按日期和时间分组。我假设你的结果中20日上午4点注销是一个疏忽,否则我们需要知道决定它应被视为当天注销时间的逻辑 一个问题是,您试图仅将日期显示为组,但您是按日期和时间分组的 请尝试以下方法:
SELECT
CAST(LI.created AS DATE) AS created,
MIN(CAST(LI.created AS TIME)) AS login,
MAX(CAST(LO.created AS TIME)) AS logout
FROM
dbo.My_Table LI
LEFT OUTER JOIN dbo.My_Table LO ON
LO.action = 'logout' AND
CAST(LO.created AS DATE) = CAST(LI.created AS DATE)
WHERE
LI.action = 'login'
GROUP BY
CAST(LI.created AS DATE)
另一个要考虑的是登录周期是否可以跨越日期边界。如果这是在科技行业,那么登录时间为下午1/20点10分,注销时间为凌晨1/21点2分并不奇怪
与Rahul的答案类似,但您可以进行自连接以获得第一次登录/最后一次注销,并按日期分组以获得您要求的结果SELECT CONVERT(DATE, li.created) [Date],
CONVERT(TIME, MIN(li.created)) [Login],
CONVERT(TIME, MAX(lo.created)) [Logout]
FROM Logins li
JOIN Logins lo
ON CONVERT(DATE, li.created) = CONVERT(DATE, lo.created)
AND li.action = 'login'
AND lo.action = 'logout'
GROUP BY CONVERT(DATE, li.created)
编辑:未测试SQL Server 2005,您可能需要为varchar设置长度
SELECT CONVERT(VARCHAR, li.created, 110) [Date],
CONVERT(VARCHAR, MAX(li.created), 8) [Login],
CONVERT(VARCHAR, MAX(lo.created), 8) [Logout]
FROM Logins li
JOIN Logins lo
ON CONVERT(VARCHAR, li.created, 110) = CONVERT(VARCHAR, lo.created, 110)
AND li.action = 'login'
AND lo.action = 'logout'
GROUP BY CONVERT(VARCHAR, li.created, 110)
.试试
按转换分组(VARCHAR(10),li.Created,10)
。你怎么知道因为某种原因04:12:22AM在同一天的08:00:00AM之后。。。?什么规则规定了选择什么时间?@JoachimIsaksson这是一个打字错误,我更正了,所以20号也应该是下午4点?@JoachimIsaksson是的,已经更正了我认为应该是登录时间04:12:22AM注销10:05.10AM…?@Rahul Tripathi我得到了所有结果的相同注销时间我也得到了所有结果的相同注销时间我还根据日期添加了一个加入
条件,我认为应该纠正这个问题。现在没有时间测试它,但希望它能起作用。@Smith你用SQL Server 2008标记了它,所以我用它进行了测试。如果您需要SQL Server 2005,也许您应该重新标记该问题。现在我想从employee表中加入员工姓名,我需要问另一个问题还是将其添加到此问题中?@Smith最好问一个新问题,因为更改一个已经有多个答案的问题通常是不受欢迎的(无论如何,你会因为一个新问题而得到更多的关注:))