【问题标题】:MySQL Join tables on weekday+hour of timestamp, count per tableMySQL在工作日+时间戳小时加入表,每个表计数
【发布时间】:2013-10-28 07:06:06
【问题描述】:

我有几个结构完全相同的表。它们包含来自年度活动入口处填写的表格的数据。这些表中的一个字段是 DATETIME,其中包含条目的日期和时间。

出于统计目的,我试图比较每年每小时的条目数量。当然,我可以为每个表运行单独的查询并在 PHP 中将它们放在一起。但我认为在一个查询中也应该可以。但是,我不知道如何构建正确的查询。

这是我目前得到的:

SELECT
    WEEKDAY(P3.AddedOn) Day,
    HOUR(P3.AddedOn) Hour,
    COUNT(P3.AddedOn) Entries2013,
    COUNT(P2.AddedOn) Entries2012
FROM Event2013 P3
LEFT JOIN Event2012 P2
    ON WEEKDAY(P3.AddedOn) = WEEKDAY(P2.AddedOn)
        AND HOUR(P3.AddedOn) = HOUR(P2.AddedOn)
GROUP BY WEEKDAY(P3.AddedOn), WEEKDAY(P2.AddedOn), HOUR(P3.AddedOn), HOUR(P2.AddedOn)

但是这个查询会产生一些奇怪的结果,其中的数字太大并且 Entries2012 和 Entries2013 列中的数字相同。它添加了一些数据,但我无法确定到底是哪个。

我做错了什么?

感谢您的帮助!

--

用子查询解决:

SELECT
    P2.Day,
    P2.Hour,
    P2.Entries Entries2012,
    P3.Entries Entries2013
FROM
    (
        SELECT
            WEEKDAY(AddedOn) Day,
            HOUR(AddedOn) Hour,
            COUNT(1) AS Entries
        FROM Event2012
        GROUP BY Day, Hour
    ) P2
LEFT JOIN
    (
        SELECT
            WEEKDAY(AddedOn) Day,
            HOUR(AddedOn) Hour,
            COUNT(1) AS Entries
        FROM Event2013
        GROUP BY Day, Hour
    ) P3
        ON P2.Day = P3.Day
            AND P2.Hour = P3.Hour

--

现在还有某种 MySQL FULL OUTER JOIN:

SELECT
    Day,
    Hour,
    Entries2012,
    Entries2013
FROM (
    SELECT
        (CASE P2.Day
            WHEN 4 THEN "Fr"
            WHEN 5 THEN "Sat"
            WHEN 6 THEN "Sun"
            ELSE P2.Day
            END) AS Day,
        P2.Hour,
        COALESCE(P2.Entries, 0) Entries2012,
        COALESCE(P3.Entries, 0) Entries2013
    FROM (
        SELECT
            WEEKDAY(AddedOn) Day,
            HOUR(AddedOn) Hour,
            COUNT(1) AS Entries
        FROM Event2012
        GROUP BY Day, Hour) P2
    LEFT JOIN (
        SELECT
            WEEKDAY(AddedOn) Day,
            HOUR(AddedOn) Hour,
            COUNT(1) AS Entries
        FROM Event2013
        GROUP BY Day, Hour) P3
    ON P2.Day = P3.Day
        AND P2.Hour = P3.Hour
    UNION SELECT
        (CASE P3.Day
            WHEN 4 THEN "Fr"
            WHEN 5 THEN "Sat"
            WHEN 6 THEN "Sun"
            ELSE P3.Day
            END) AS Day,
        P3.Hour,
        COALESCE(P2.Entries, 0) Entries2012,
        COALESCE(P3.Entries, 0) Entries2013
    FROM (
        SELECT
            WEEKDAY(AddedOn) Day,
            HOUR(AddedOn) Hour,
            COUNT(1) AS Entries
        FROM Event2012
        GROUP BY Day, Hour) P2
    RIGHT JOIN (
        SELECT
            WEEKDAY(AddedOn) Day,
            HOUR(AddedOn) Hour,
            COUNT(1) AS Entries
        FROM Event2013
        GROUP BY Day, Hour) P3
    ON P2.Day = P3.Day
        AND P2.Hour = P3.Hour
    WHERE P2.Hour IS NULL) AS tmp
ORDER BY Day, Hour

【问题讨论】:

    标签: mysql datetime join count timestamp


    【解决方案1】:

    LEFT JOIN 表示您打算从 P3 中获取所有条目,并期望其中一些在 P2 中不匹配。如果 P3 是您的基表(并且您在另一个表中查找可能的匹配项),您只需按 P3 列分组。

    SELECT P3.Day Day, P3.Hour Hour, Entries2013, Entries2012 
    FROM (
    SELECT   
        WEEKDAY(AddedOn) Day,
        HOUR(AddedOn) Hour,
        COUNT(AddedOn) Entries2013
        GROUP BY Day, Hour
    FROM Event2013) P3
    LEFT JOIN (
    SELECT 
        WEEKDAY(AddedOn) Day,
        HOUR(AddedOn) Hour,
        COUNT(AddedOn) Entries2012
        GROUP BY Day, Hour
    FROM Event2012) P2
    ON P3.DAY = P2.DAY
    AND P3.Hour = P2.Hour
    GROUP BY P3.Day, P3.Hour;
    

    此外,使用 WEEKDAY 意味着您将给定年份的所有星期一、星期二等相加,然后从中获取每小时汇总。如果您想获取每日摘要(其中一天是一年中的哪一天),您应该使用 DAYOFYEAR i/o WEEKDAY。

    【讨论】:

    • 我后来在GROUP BY 中添加了额外的列。不幸的是,省略它们并不会改变结果。
    • WEEKDAY 的分组是故意的(但可能是错误的?)。该活动每年在周六和周日举行一次。我正在寻找的结果应该允许我比较两年的上午 9 点到 10 点之间的星期六的条目数量。
    【解决方案2】:

    查看UNION语句:http://dev.mysql.com/doc/refman/5.0/en/union.html

    这结合了来自两个表的查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2019-10-25
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 2014-02-22
      • 1970-01-01
      相关资源
      最近更新 更多