简体   繁体   English

SQL查询每小时报告?

[英]SQL query hourly report?

I have a bit of a tough one beating me here. 我有一个艰难的人在这里殴打我。 We have a production warehouse where various products are created, we send out a daily production report using the following query but i would like to have this sorted hourly: 我们有一个生产各种产品的生产仓库,我们使用以下查询发送每日生产报告,但我希望每小时进行一次排序:

(Im trimming down the query to only a few products as its quite a biggie: (我将查询精简为仅几个产品,因为它相当大:

SET

@DayStart = '2013-10-24 07:00:00',
@DayEnd = '2013-10-24 16:00:00';

SELECT 
(SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '3'

) AS Product1,

(SELECT CONCAT (
    (SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '10'
    AND status_id = '4'
    ) , ' / ' ,
    (SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '10'
    AND status_id = '6'
    ))
) AS 'Product 1 EOL',

(SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '2'
    ) AS 'Product 2',

(SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '6'
    ) AS 'Product 3',

(SELECT CONCAT (
    (SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '9'
    AND status_id = '4'
    ) , ' / ' ,
    (SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '9'
    AND status_id = '6'
    ))
) AS 'Product 3 EOL',

(SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '4'
) AS 'Product 4',

(SELECT CONCAT (
    (SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '8'
    AND status_id = '4'
    ) , ' / ' ,
    (SELECT COUNT(*) FROM t_container
    WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
    AND container_type_id = '8'
    AND status_id = '6'
    ))
) AS 'Product 4 EOL'

What i would like to achieve is to have the above report to run but the output be in 1 hour increments. 我想实现的是运行以上报告,但输出以1小时为增量。

Any assistance would be greatly appreciated. 任何帮助将不胜感激。

Please see below "expected output example" 请参见下面的“预期输出示例”

TIME | 时间| Product 1 | 产品1 | Product 1 EOL | 产品1停产| Product 2 | 产品2 | Product 3 产品3
07:00 | 07:00 | 12345 | 12345 | 1 / 1 | 1/1 | 1568789 | 1568789 | 1 / 1 1/1
08:00 | 08:00 | 12345 | 12345 | 1 / 1 | 1/1 | 1568789 | 1568789 | 1 / 1 1/1
09:00 | 09:00 | 12345 | 12345 | 1 / 1 | 1/1 | 1568789 | 1568789 | 1 / 1 1/1

You have a row which contains a LOT of subselects 您有一行包含很多子选择

I would be tempted to recode these to subselect which are then joined into a single row (or just return multiple rows and do the formatted in you display code). 我很想将它们重新编码为子选择,然后再将它们加入到单行中(或仅返回多行并按照显示代码的格式进行格式化)。

However to split one of those subselects up into hours you could use something like this (not tested):- 但是,要将这些子选择之一分成几个小时,您可以使用类似以下内容(未经测试):-

SELECT StartHour, COUNT(*) 
FROM 
(
    SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour
    FROM
    (
        SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
    ) Sub1
) Sub2
LEFT OUTER JOIN t_container
ON created_timestamp BETWEEN Sub2.StartHour AND DATE_ADD(Sub2.StartHour, INTERVAL 3599 SECOND)
WHERE created_timestamp BETWEEN @DayStart AND @DayEnd
AND container_type_id = '3'
GROUP BY StartHour

This comes up with a range of hour time bands by adding to the start date, then uses that to do a left join against you data (adding 3599 seconds to get the end of the hour time bands), and doing a grouped count, doing GROUP BY on the starting hour. 通过添加开始日期来设置小时范围,然后使用该范围对您的数据进行左连接(添加3599秒以获取小时结束时间段),并进行分组计数,在开始时间的GROUP BY。

EDIT 编辑

Not tested, but here is one way of doing it:- 未经测试,但这是一种实现方法:-

SELECT StartHour, 
        EndHour, 
        COUNT(DISTINCT a.id) AS Product1,
        COUNT(DISTINCT b.id) AS 'Product 1 EOL 1',
        COUNT(DISTINCT c.id) AS 'Product 1 EOL 2',
        COUNT(DISTINCT d.id) AS 'Product 2',
        COUNT(DISTINCT e.id) AS 'Product 3',
        COUNT(DISTINCT f.id) AS 'Product 3 EOL 1',
        COUNT(DISTINCT g.id) AS 'Product 3 EOL 2',
        COUNT(DISTINCT h.id) AS 'Product 4',
        COUNT(DISTINCT i.id) AS 'Product 4 EOL 1',
        COUNT(DISTINCT j.id) AS 'Product 4 EOL 2'
FROM 
(
    SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
    FROM
    (
        SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
    ) Sub1
) Sub2
LEFT OUTER JOIN t_container a
ON a.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND a.container_type_id = '3'
LEFT OUTER JOIN t_container b
ON b.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND b.container_type_id = '10'
AND b.status_id = '4'
LEFT OUTER JOIN t_container c
ON c.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND c.container_type_id = '10'
AND c.status_id = '6'
LEFT OUTER JOIN t_container d
ON d.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND d.container_type_id = '2'
LEFT OUTER JOIN t_container e
ON e.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND e.container_type_id = '6'
LEFT OUTER JOIN t_container f
ON f.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND f.container_type_id = '9'
AND f.status_id = '4'
LEFT OUTER JOIN t_container g
ON g.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND g.container_type_id = '9'
AND g.status_id = '6'
LEFT OUTER JOIN t_container h
ON h.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND h.container_type_id = '4'
LEFT OUTER JOIN t_container i
ON i.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND i.container_type_id = '8'
AND i.status_id = '4'
LEFT OUTER JOIN t_container j
ON j.created_timestamp BETWEEN Sub2.StartHour AND Sub2.EndHour
AND j.container_type_id = '8'
AND j.status_id = '6'
GROUP BY StartHour, EndHour

This is doing 1 subselect to get all the hour time bands, then joining the tables back to get the counts. 这样做是进行1次子选择以获取所有小时时间段,然后将表重新连接以获取计数。 However using so many COUNT(DISTINCT )) type statements might not perform that well. 但是,使用这么多的COUNT(DISTINCT))类型的语句可能效果不佳。

Probably be possible to do the joins to get the hour ranges in each of the subselects that are then joined back, which might be better. 可能有可能进行联接以获取每个子选择中的小时范围,然后再联接回去,这可能更好。

Note that I have brought back 2 columns for the columns that previously had 2 values split by a /. 请注意,我为以前有2个值(用/分隔)的列带回了2列。

Possibly slightly better (but also possibly slightly worse):- 可能稍好(但也可能稍差):-

SELECT Product1.rec_cnt AS Product1,
        CONCAT(Product1EOL1.rec_cnt, ' / ', Product1EOL2.rec_cnt) AS 'Product 1 EOL',
        Product2.rec_cnt AS 'Product 2',
        Product3.rec_cnt AS 'Product 3',
        CONCAT(Product3EOL1.rec_cnt, ' / ', Product3EOL2.rec_cnt) AS 'Product 3 EOL',
        Product4.rec_cnt AS 'Product 4',
        CONCAT(Product4EOL1.rec_cnt, ' / ', Product4EOL2.rec_cnt) AS 'Product 4 EOL'
FROM
(
    SELECT StartHour, EndHour, COUNT(t_container.id)  AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '3'
    GROUP BY StartHour, EndHour
) AS Product1
INNER JOIN
(
    SELECT StartHour, EndHour, COUNT(t_container.id)  AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '10'
    AND status_id = '4'
    GROUP BY StartHour, EndHour
) AS Product1EOL1
ON Product1.StartHour = Product1EOL1.StartHour AND Product1.EndHour = Product1EOL1.EndHour
INNER JOIN
(
    SELECT StartHour, EndHour, COUNT(t_container.id)  AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '10'
    AND status_id = '6'
    GROUP BY StartHour, EndHour
) AS Product1EOL2
ON Product1.StartHour = Product1EOL2.StartHour AND Product1.EndHour = Product1EOL2.EndHour
INNER JOIN
(
    SELECT StartHour, EndHour, COUNT(t_container.id)  AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '2'
    GROUP BY StartHour, EndHour
) AS Product2
ON Product1.StartHour = Product2.StartHour AND Product1.EndHour = Product2.EndHour
INNER JOIN
(
    SELECT StartHour, EndHour, COUNT(t_container.id)  AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '6'
    GROUP BY StartHour, EndHour
) AS Product3
ON Product1.StartHour = Product3.StartHour AND Product1.EndHour = Product3.EndHour
INNER JOIN
(
    SELECT StartHour, EndHour, COUNT(t_container.id)  AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '9'
    AND status_id = '4'
    GROUP BY StartHour, EndHour
) AS Product3EOL1
ON Product1.StartHour = Product3EOL1.StartHour AND Product1.EndHour = Product3EOL1.EndHour
INNER JOIN
(
    SELECT StartHour, EndHour, COUNT(t_container.id)  AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '9'
    AND status_id = '6'
    GROUP BY StartHour, EndHour
) AS Product3EOL2
ON Product1.StartHour = Product3EOL2.StartHour AND Product1.EndHour = Product3EOL2.EndHour
INNER JOIN
(
    SELECT StartHour, EndHour, COUNT(t_container.id)  AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '4'
    GROUP BY StartHour, EndHour
) AS Product4
ON Product4.StartHour = Product3.StartHour AND Product4.EndHour = Product3.EndHour
INNER JOIN
(
    SELECT StartHour, EndHour, COUNT(t_container.id)  AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '8'
    AND status_id = '4'
    GROUP BY StartHour, EndHour
) AS Product4EOL1
ON Product1.StartHour = Product4EOL1.StartHour AND Product1.EndHour = Product4EOL1.EndHour
INNER JOIN
(
    SELECT StartHour, EndHour, COUNT(t_container.id) AS rec_cnt
    FROM 
    (
        SELECT DATE_ADD(@DayStart, INTERVAL i HOUR) AS StartHour, DATE_ADD(DATE_ADD(@DayStart, INTERVAL i HOUR), INTERVAL 3599 SECOND) AS EndHour
        FROM
        (
            SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
        ) Sub1
    ) Sub2
    LEFT OUTER JOIN t_container
    ON created_timestamp BETWEEN StartHour AND EndHour
    AND container_type_id = '8'
    AND status_id = '6'
    GROUP BY StartHour, EndHour
) AS Product4EOL2
ON Product1.StartHour = Product4EOL2.StartHour AND Product1.EndHour = Product4EOL2.EndHour

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM