5

チャート作成のためにこれが必要です。基本的に私はしなければなりません:

  1. 送信されたすべての SMS を時刻部分なしで日付別に選択し、日ごとの日付/カウントのペアを含む配列を取得します。
  2. テーブルにレコードがない日の「偽の」行を追加します。つまり、すべての日付の「ギャップ」をゼロで埋めます。

結果の例と対応する表 (ここでは簡略化) は次のようになります。

array(
    '2012-05-26 00:00:00' => 1,
    '2012-05-27 00:00:00' => 0, // Fake added row
    '2012-05-28 00:00:00' => 2,
)

+----------------+----------------------+
| Table SMS | id | sent_at              |
+----------------+----------------------+
|           |  1 | 2012-05-26 21:58:41  |
+----------------+----------------------+
|           |  2 | 2012-05-28 22:19:21  |
+----------------+----------------------+
|           |  3 | 2012-05-28 02:19:21  |
+----------------+----------------------+

これを行うための SQL コマンドはありますか、それとも PHP 配列を手動で操作する必要がありますか?

4

2 に答える 2

4

UNIONステートメントを使用できます

SELECT 
   sent_at,
   Count(*)
FROM (Select
        id,
        DATE(sent_at) as sent_at
      FROM TableName 
      Group by Date(sent_at)
      UNION ALL
      Select
        '0' as id,
        DATE('2012-05-27') as sent_at) derived_table
Group By sent_at

編集済み

結合する特別なテーブルを作成することを提案しました。

クエリ用の日付テーブルの作成

CREATE TABLE DateTable (
  DateValue DateTime,
  Year Int,
  Month Int,
  Day Int)

ここで、クエリ対象の範囲内のすべての日付値をこのテーブルに入力します。有効な日付を指定して、このテーブルに簡単に参加できます。存在する日付と存在しない日付を集計できます。

于 2012-05-29T00:17:06.383 に答える
1

はい、私はいつもこれを行います

DROP PROCEDURE IF EXISTS `Example`;
DELIMITER $$

CREATE PROCEDURE `Example` (
    $StartDate DATE,
    $EndDate DATE
    )
BEGIN

    DECLARE $curDay DATE;
    SET $StartDate = IFNULL($StartDate,'2000-01-01');
    SET $curDay = $StartDate;


    DROP TEMPORARY TABLE IF EXISTS `Day`;
    CREATE TEMPORARY TABLE `Day`(
        `Date` DATE
    );

    DaysLoop:LOOP

        INSERT INTO
            `Day`(`Date`)
        SELECT 
            $curDay
        ;

        SET $curDay = $curDay + INTERVAL 1 DAY;

        IF 
            $curDay >= $EndDate OR $curDay >= NOW()
        THEN 
            LEAVE DaysLoop;
        END IF;

    END LOOP DaysLoop;

    SELECT
        D.Date,
        COUNT(S.id)
    FROM
        `Day` AS D
    LEFT JOIN
        `SMS` AS S
        ON D.Date = DATE(S.sent_at)
    GROUP BY
        D.Date
    ORDER BY
        D.Date
    ;

END $$

DELIMITER ;

CALL Example('2012-01-01','2012-05-01');

レポートにはストアド プロシージャを使用することをお勧めしますが、作成スクリプトなどをバージョン管理するようにしてください。

于 2012-05-29T03:25:09.020 に答える