如何填补MySQL中的日期空白?

时间:2009-12-10 00:18:56

标签: sql mysql

我如何填补MySQL中的日期空白?这是我的疑问:

SELECT DATE(posted_at) AS date,
    COUNT(*) AS total,
    SUM(attitude = 'positive') AS positive,
    SUM(attitude = 'neutral') AS neutral,
    SUM(attitude = 'negative') AS negative
    FROM `messages`
    WHERE (`messages`.brand_id = 1)
    AND (`messages`.`spam` = 0
    AND `messages`.`duplicate` = 0
    AND `messages`.`ignore` = 0)
    GROUP BY date ORDER BY date

它返回正确的结果集 - 但我希望用零填充日期开始和结束之间的间隙。我怎么能这样做?

2 个答案:

答案 0 :(得分:4)

您需要创建一个帮助程序表,并用startend填充所有日期,然后只填充LEFT JOIN该表:

SELECT  d.dt AS date,
        COUNT(*) AS total,
        SUM(attitude = 'positive') AS positive,
        SUM(attitude = 'neutral') AS neutral,
        SUM(attitude = 'negative') AS negative
FROM    dates d
LEFT JOIN
        messages m
ON      m.posted_at >= d.dt
        AND m.posted_at < d.dt + INTERVAL 1 DAYS
        AND spam = 0
        AND duplicate = 0
        AND ignore = 0
GROUP BY
        d.dt
ORDER BY
        d.dt

基本上,你需要的是虚拟行源。

MySQL是唯一缺乏生成方法的主要系统。

PostgreSQL实现了一个特殊功能generate_series,而OracleSQL Server可以使用递归(CONNECT BY和递归CTE ,相应地)。

答案 1 :(得分:0)

我不知道MySQL是否支持以下/类似语法;但如果没有,那么你可以创建并删除一个临时表。

--Inputs
declare @FromDate datetime, /*Inclusive*/
        @ToDate datetime    /*Inclusive*/
set @FromDate = '20091101'
set @ToDate = '20091130'

--Query
declare @Dates table (
    DateValue datetime NOT NULL
)
set NOCOUNT ON
while @FromDate <= @ToDate /*Inclusive*/
begin
  insert into @Dates(DateValue) values(@FromDate)
  set @FromDate = @FromDate + 1
end
set NOCOUNT OFF

select  dates.DateValue,
        Col1...
from    @Dates dates
        left outer join SourceTableOrView data on
            data.DateValue >= dates.DateValue
        and data.DateValue < dates.DateValue + 1 /*NB: Exclusive*/
where   ...?