【问题标题】:complex sql grouping and sorting复杂的sql分组和排序
【发布时间】:2012-09-07 04:34:50
【问题描述】:

我在将每日时间记录中的数据分组和排序时遇到问题 自动生成报告。 DTR的表结构如下:

LogDate LogTime EmployeeName LogType 2012-09-14 10:48:04 SALITA, LYNYRD ANTONIO 注销 2012-09-14 09:39:29 SALITA,LYNYRD ANTONIO 注销 2012-09-14 09:39:19 SALITA, LYNYRD ANTONIO 登录 2012-09-14 09:35:25 SALITA,LYNYRD ANTONIO 注销 2012-09-14 09:35:13 SALITA, LYNYRD ANTONIO 登录 2012-09-14 08:10:00 SALITA,LYNYRD ANTONIO 登录 2012-09-13 17:00:00 SALITA,LYNYRD ANTONIO 注销 2012-09-13 08:05:00 SALITA, LYNYRD ANTONIO 登录 2012-09-12 17:05:00 SALITA,LYNYRD ANTONIO 注销 2012-09-12 08:05:00 SALITA, LYNYRD ANTONIO 登录 2012-07-10 17:00:00 MAG-ISA,美宝莲登出 2012-07-10 17:00:00 BELO,里约热内卢注销 2012-07-10 17:00:00 卡西诺,保罗登出 2012-07-10 17:00:00 SALITA,LYNYRD ANTONIO 注销 2012-07-10 17:00:00 AURENO,莉亚登出 2012-07-10 17:00:00 加西亚,阿尔文登出 2012-07-10 17:00:00 TARINE,凯伦登出 2012-07-10 17:00:00 REYES,ANDREA 注销 2012-07-10 17:00:00 纳瓦罗,克里斯蒂娜 注销 2012-07-10 10:30:00 MAG-ISA,美宝莲登录 2012-07-10 08:00:00 SALITA,LYNYRD ANTONIO 登录 2012-07-10 08:00:00 卡西诺,保罗登录 2012-07-10 08:00:00 贝洛,里约登录 2012-07-10 07:40:00 AURENO,莉亚登录 2012-07-10 07:30:00 加西亚,阿尔文登录 2012-07-10 07:25:00 TARINE,凯伦登录 2012-07-10 07:10:00 纳瓦罗,克里斯蒂娜登录 2012-07-10 07:10:00 REYES,ANDREA 登录

使用这个 sql:

SELECT 
    DATE_FORMAT(LogDate, '%d/%c/%Y') AS LogDate, 
    EmployeeName,
    (GROUP_Concat(CASE LogType WHEN 'LOGIN' THEN LogTime END)) AS LOGIN,
    (GROUP_Concat(CASE LogType WHEN 'LOGOUT' THEN LogTime END)) AS LOGOUT
FROM myTable
GROUP BY LogDate, EmployeeName
ORDER BY LogDate desc;

我能够产生这个结果

LogDate EmployeeName 登录 注销 2012-09-14 SALITA, LYNYRD ANTONIO 08:10:00,09:35:13,09:39:19 09:35:25,09:39:29,10:48:04 2012-09-13 SALITA, LYNYRD 安东尼奥 08:05:00 17:00:00 2012-09-12 SALITA, LYNYRD 安东尼奥 08:05:00 17:05:00 2012-07-10 雷耶斯,安德烈亚 07:10:00 17:00:00 2012-07-10 纳瓦罗,克里斯蒂娜 07:10:00 17:00:00 2012-07-10 塔林,凯伦 07:25:00 17:00:00 2012-07-10 加西亚,阿尔文 07:30:00 17:00:00 2012-07-10 奥雷诺,莉亚 07:40:00 17:00:00 2012-07-10 卡西诺,保罗 08:00:00 17:00:00 2012-07-10 萨利塔,林尼德安东尼奥 08:00:00 17:00:00 2012-07-10 贝洛,里约热内卢 08:00:00 17:00:00 2012-07-10 MAG-ISA, MAYBELLE 10:30:00 17:00:00

根据其中一个答案,这是代码:

SELECT DATE_FORMAT(t1.LogDate, '%d/%c/%Y') AS LogDate, t1.EmployeeName
     , t1.LogTime AS Login
     , ( SELECT MIN(t2.LogTime) FROM myTable t2
          WHERE t2.LogType = 'LOGOUT'
            AND t2.LogDate = t1.LogDate
            AND t2.EmployeeName = t1.EmployeeName
            AND t2.LogTime > t1.LogTime ) AS Logout
  FROM myTable t1
 WHERE t1.LogType = 'LOGIN'

它产生了这个结果:

LogDate EmployeeName 登录 注销 2012-09-14 SALITA, LYNYRD 安东尼奥 08:10:00 09:35:25 2012-09-14 萨利塔,林尼德安东尼奥 09:35:13 09:35:25 2012-09-14 SALITA, LYNYRD ANTONIO 09:39:19 09:39:29 2012-09-13 SALITA, LYNYRD 安东尼奥 08:05:00 17:00:00 2012-09-12 SALITA, LYNYRD 安东尼奥 08:05:00 17:05:00 2012-07-10 雷耶斯,安德烈亚 07:10:00 17:00:00 2012-07-10 纳瓦罗,克里斯蒂娜 07:10:00 17:00:00 2012-07-10 塔林,凯伦 07:25:00 17:00:00 2012-07-10 加西亚,阿尔文 07:30:00 17:00:00 2012-07-10 奥雷诺,莉亚 07:40:00 17:00:00 2012-07-10 卡西诺,保罗 08:00:00 17:00:00 2012-07-10 萨利塔,林尼德安东尼奥 08:00:00 17:00:00 2012-07-10 贝洛,里约热内卢 08:00:00 17:00:00 2012-07-10 MAG-ISA, MAYBELLE 10:30:00 17:00:00

有没有办法让结果变成这样?

LogDate EmployeeName 登录 注销 2012-09-14 SALITA,LYNYRD ANTONIO 08:10:00 NULL 2012-09-14 萨利塔,林尼德安东尼奥 09:35:13 09:35:25 2012-09-14 SALITA, LYNYRD ANTONIO 09:39:19 09:39:29 2012-09-14 SALITA,LYNYRD ANTONIO NULL 10:48:04 2012-09-13 SALITA, LYNYRD 安东尼奥 08:05:00 17:00:00 2012-09-12 SALITA, LYNYRD 安东尼奥 08:05:00 17:05:00 2012-07-10 雷耶斯,安德烈亚 07:10:00 17:00:00 2012-07-10 纳瓦罗,克里斯蒂娜 07:10:00 17:00:00 2012-07-10 塔林,凯伦 07:25:00 17:00:00 2012-07-10 加西亚,阿尔文 07:30:00 17:00:00 2012-07-10 奥雷诺,莉亚 07:40:00 17:00:00 2012-07-10 卡西诺,保罗 08:00:00 17:00:00 2012-07-10 萨利塔,林尼德安东尼奥 08:00:00 17:00:00 2012-07-10 贝洛,里约热内卢 08:00:00 17:00:00 2012-07-10 MAG-ISA, MAYBELLE 10:30:00 17:00:00

【问题讨论】:

    标签: mysql sql sorting grouping


    【解决方案1】:

    类似这样的:

    SELECT DATE_FORMAT(t1.LogDate, '%d/%c/%Y') AS LogDate, t1.EmployeeName
         , t1.LogTime AS Login
         , ( SELECT MIN(t2.LogTime) FROM myTable t2
              WHERE t2.LogType = 'LOGOUT'
                AND t2.LogDate = t1.LogDate
                AND t2.EmployeeName = t1.EmployeeName
                AND t2.LogTime > t1.LogTime ) AS Logout
      FROM myTable t1
     WHERE t1.LogType = 'LOGIN'
    

    实际上不需要 GROUP BY,因为您实际上并没有对任何内容进行分组。

    【讨论】:

    • AND t2.LogDate = t1.LogDate 可能是多余的,因为可能会在午夜后注销)
    • 是的,只要 LogTime 是 DATETIME 我认为你是对的。
    • 哇这个也有用!但是有没有一种方法可以使未配对的登录时间显示 null 而不是未配对登录的下一次注销或未配对注销的上一次登录?
    • 您能定义未配对的日志时间是什么意思吗?用户是否可以登录,而不是注销,然后再次登录?或者除非用户实际登录,否则总会有匹配的注销事件?
    • 我只是添加了另一个注销,以便让员工 salita 登录,然后登录并注销,然后再次注销。这为 salita 生成了 3 条记录,但我不知道系统在哪里获取未配对注销的登录信息,它不是以前的登录信息。这是您的代码的结果,其中包含数据库的新条目,即员工 salita 的注销:
       2012-09-14 SALITA, LYNYRD ANTONIO 08:10:00 09:35:25 2012-09-14 SALITA , LYNYRD ANTONIO 09:35:13 09:35:25 2012-09-14 SALITA, LYNYRD ANTONIO 09:39:19 09:39:29 
    猜你喜欢
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多