6

時間ごとにレコードをカウントするクエリを作成しました。

select TO_CHAR(copied_timestamp, 'YYYY-MM-DD HH24'),count(*) from req group by
TO_CHAR(copied_timestamp, 'YYYY-MM-DD HH24');

結果は次のとおりです。

2012-02-22 13    2280
2012-02-22 15    1250
2012-02-22 16    1245
2012-02-22 19    1258

しかし、次のような結果が必要です。

2012-02-22 13    2280
2012-02-22 14    0
2012-02-22 15    1250
2012-02-22 16    1245
2012-02-22 17    0
2012-02-22 18    0
2012-02-22 19    1258

また、日と月ごとにグループ化するこれらのクエリもあります。

select TO_CHAR(copied_timestamp, 'YYYY-MM-DD'),count(*)  from req
group by TO_CHAR(copied_timestamp, 'YYYY-MM-DD');

select TO_CHAR(copied_timestamp, 'YYYY-MM'),count(*)  from req
group by TO_CHAR(copied_timestamp, 'YYYY-MM');

それらのギャップもゼロまたはヌルで埋める必要があります。どんな助けでも本当に感謝しています。

注:Oracleを使用してこの質問に対する回答がありますが、CONNECT BYMysqlはサポートしていないため、Mysqlで回答が必要CONNECT BYです。 ここにリンクがあります

4

2 に答える 2

2

TBL_NUMBERS というテーブルを作成しました

CREATE TABLE `TBL_NUMBER` (`n` int(11) NOT NULL)

1 から 1000 までのレコードを挿入しました。これで、次のクエリを使用してあらゆる種類の日付範囲を生成できます。

SELECT '2012-06-21' + INTERVAL n-1 [DAY | HOUR | MINUTE] or as dateRange
 FROM TBL_NUMBER
WHERE '2012-06-21' + INTERVAL n-1 [DAY | HOUR | MINUTE] <= '2012-06-23';

次に、このテーブルを結果と結合して、日付のギャップを埋めることができます。1000 を超える日付範囲が必要な場合は、より多くのレコードを挿入できますTBL_NUMBER

もっと良いアイデアがあれば、私はそれを知りたいです;)

于 2012-07-03T08:37:55.390 に答える
2

dates_hours妥当な範囲 (例: 1900 から 2200) 内のすべての日付と時間を含む単一列のテーブルを生成します。次にLEFT JOIN、このテーブルから現在のクエリに対して a を実行します。

この手法を正しく実行するには、おそらく、変換されたタイム スタンプを含むインデックス付きの列をテーブルに追加する必要があります (にcopied_timestamp変換されDATETIME、時間に丸められます) 。

SELECT date_hour, count(req.converted_timestamp)
FROM
    dates_hours 
    LEFT JOIN req ON req.converted_timestamp = dates_hours.date_hour
WHERE date_hour
    BETWEEN (SELECT MIN(req.converted_timestamp) FROM req)
    AND (SELECT MAX(req.converted_timestamp) FROM req)
GROUP BY date_hour

dates_hoursテーブルを生成するには:

CREATE TABLE dates_hours (date_hour DATETIME PRIMARY KEY);

DELIMITER $$$
CREATE PROCEDURE generate_dates_hours (to_date DATETIME)
BEGIN

    DECLARE start_date DATETIME;
    DECLARE inc INT;

    SELECT MAX(date_hour) INTO start_date FROM dates_hours;
    IF start_date IS NULL THEN
        SET start_date = '1900-01-01';
    END IF;
    SET inc = 1;
    WHILE start_date + INTERVAL inc HOUR  <= to_date DO
        INSERT INTO dates_hours VALUE (start_date + INTERVAL inc HOUR);
        SET inc = inc +1;
    END WHILE;

END $$$
DELIMITER ;

CALL generate_dates_hours('2200-01-01');

さて、私は自分自身を校正しているので、これは非常にとてつもない解決策であることに気付きました. 誰かがもっとエレガントなものを思いつくことを願っています。

于 2012-07-02T23:51:52.110 に答える