【问题标题】:Merge two rows with different date but with the same attributes合并具有不同日期但具有相同属性的两行
【发布时间】:2013-07-31 21:10:38
【问题描述】:

我有这个问题

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

谁能帮我弄清楚我要改变什么或提出一个新的解决方案?谢谢。

【问题讨论】:

    标签: php mysql sql select group-by


    【解决方案1】:

    好吧,我终于能够解决我自己的问题了。这是我作为 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
    

    顺便说一句,我决定不再删除日期,因为我也发现它很有用。

    注意:这可能不是最好的答案,也不是最好的设计或架构,但这是我作为 SQL 新手所能做的最好的。如果您有比这更好的解决方案,请分享它,而不仅仅是吠叫感谢。 :)

    【讨论】:

    • 这可能行得通,但恐怕它是靠运气而不是设计实现的,因此不应将其作为解决方案。
    • 嗯,是的,我明白这一点,因为我只是 sql 的新手。我刚开始学习,还不擅长设计。但事实是,我尝试并尽我所能去做,而不仅仅依赖于其他人的答案。我知道这可能不是最好的解决方案,但没关系,因为它满足了我的需求。而不是等待多年才能得到一个擅长设计的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    相关资源
    最近更新 更多