1

ここで私を打ち負かすのは少しタフなものです。さまざまな製品が作成される生産倉庫があり、次のクエリを使用して毎日の生産レポートを送信しますが、これを 1 時間ごとに並べ替えたいと考えています。

(非常に重要なため、クエリをいくつかの製品のみに絞り込んでいます:

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'

私が達成したいのは、上記のレポートを実行することですが、出力は 1 時間単位になります。

どんな援助でも大歓迎です。

以下の「期待される出力例」を参照してください。

時間 | 製品 1 | 製品 1 EOL | 製品 2 | 製品 3
07:00 | 12345 | 1 / 1 | 1568789 | 1 / 1
08:00 | 12345 | 1 / 1 | 1568789 | 1 / 1
09:00 | 12345 | 1 / 1 | 1568789 | 1 / 1

4

1 に答える 1

1

多くの副選択を含む行があります

これらを再コード化してサブ選択し、それを単一の行に結合したくなるでしょう (または、単に複数の行を返し、表示コードでフォーマットを実行します)。

ただし、これらの副選択の 1 つを時間に分割するには、次のようなものを使用できます (テストされていません):-

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

これは、開始日に追加することによって時間帯の範囲を考え出し、それを使用してデータに対して左結合を行い (3599 秒を追加して時間帯の終わりを取得します)、グループ化されたカウントを実行します。開始時間の GROUP BY。

編集

テストされていませんが、これを行う1つの方法があります:-

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

これは、すべての時間帯を取得するために 1 つの副選択を行ってから、テーブルを再び結合してカウントを取得します。ただし、非常に多くの COUNT(DISTINCT )) 型ステートメントを使用すると、パフォーマンスが低下する可能性があります。

おそらく結合を実行して、各副選択で時間範囲を取得し、結合して戻すことが可能である可能性があります。

以前は 2 つの値が / で分割されていた列を 2 つの列に戻したことに注意してください。

おそらくわずかに良い(しかし、おそらくわずかに悪い):-

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
于 2013-10-24T08:34:03.313 に答える