5

我需要这个用于图表目的。基本上我必须:

  1. 按日期选择所有发送的短信,不带时间部分,逐日获取包含日期/计数对的数组;
  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 回答