合并具有不同日期但具有相同属性的两行

时间:2013-07-31 11:11:48

标签: php mysql sql select group-by

我有这个查询

SELECT te.user_name, LEFT(te.entry_datetime, 10) AS entry_date, cin.entry_datetime AS timein, cout.entry_datetime AS timeout
FROM time_entries te
LEFT JOIN (SELECT user_name, LEFT(entry_datetime, 10) AS entry_date, MIN(entry_datetime) AS entry_datetime
    FROM time_entries
    WHERE entry_type = 'Time In'
    GROUP BY user_name, entry_date
) cin ON cin.user_name = te.user_name AND cin.entry_date = LEFT(te.entry_datetime, 10)
LEFT JOIN (SELECT user_name, LEFT(entry_datetime, 10) AS entry_date, MAX(entry_datetime) AS entry_datetime
    FROM time_entries
    WHERE entry_type = 'Time Out'
    GROUP BY user_name, entry_date
) cout ON cout.user_name = te.user_name AND cout.entry_date = LEFT(te.entry_datetime, 10)
GROUP BY te.user_name, entry_date;

这是输出SQLFIDDLE

USER_NAME|  ENTRY_DATE   | TIMEIN    | TIMEOUT
User1    | 28-JUL-13     | 16:40:40  | 16:42:30
User2    | 28-JUL-13     | 16:41:13  | 16:41:15

但我在解决方案中找到了一个循环漏洞,他们是一些员工,他们在一夜之间工作,并在第二天停工。因此,当用户在2013年7月28日告知时间到2013年7月29日超时时,这将是输出。 SQLFIDDLE

USER_NAME|  ENTRY_DATE   | TIMEIN   | TIMEOUT
User1    | 28-JUL-13     | 16:40:40 | null
User1    | 29-JUL-13     | null     | 16:42:30
User2    | 28-JUL-13     | 16:41:13 | 16:41:15

逻辑是正确的,但在我的情况下似乎并不合适。我想只是为了让工作更轻松,只需删除ENTRY_DATE,并且只有3列USER_NAME,TIMEIN和TIMEOUT。这样的事情。

USER_NAME   | TIMEIN              | TIMEOUT
User1       | 28-JUL-13 16:40:40  | 29-JUL-13 16:42:30
User2       | 28-JUL-13 16:41:13  | 28-JUL-13 16:41:15

有谁可以帮我弄清楚我要改变什么或建议一个新的解决方案?感谢。

1 个答案:

答案 0 :(得分:0)

好吧最后我能够解决自己的问题。以下是我发现的 NEWBIE SQLFIDDLE

的解决方案
SELECT te.user_name, date(te.entry_datetime) as date, te3.entry_datetime as Timein, te2.entry_datetime as Timeout
FROM time_entries te

JOIN time_entries te3 ON te.user_name = te3.user_name
AND te3.entry_type='Time In' AND te3.entry_datetime =
    (SELECT entry_datetime
     FROM time_entries
     WHERE entry_type='Time In' AND user_name=te.user_name AND entry_datetime = te.entry_datetime
     GROUP By entry_datetime)

LEFT JOIN time_entries te2 ON te.user_name = te2.user_name
AND te2.entry_type='Time Out' AND te2.entry_datetime =
    (SELECT entry_datetime
    FROM time_entries
    WHERE entry_type='Time Out' AND user_name=te.user_name AND entry_datetime > te.entry_datetime
    ORDER BY
    ABS(TIMESTAMPDIFF(SECOND, te.entry_datetime, 'entry_datetime'))
    LIMIT 1)

示例输出:

USER_NAME|    DATE     | TIMEIN              | TIMEOUT
User1    |  28-JUL-13  | 28-JUL-13 16:40:40  | 29-JUL-13 16:42:30
User2    |  29-JUL-13  | 29-JUL-13 16:43:16  | null
User1    |  30-JUL-13  | 30-JUL-13 16:47:16  | 31-JUL-13 16:50:32

btw我决定不再删除日期,因为我发现它很有用。

注意:这可能不是最好的答案或最好的设计或架构,但这是我作为SQL新手的最佳选择。如果你有更好的解决方案,请分享它,而不仅仅是感谢它。 :)