mysql如果结果不存在则返回0

时间:2015-05-26 23:30:43

标签: mysql

我有查询

SELECT FROM_UNIXTIME(1800 * FLOOR(date/1800)) AS period_start, 
       COUNT(*) AS count 
FROM readed_messages
GROUP BY period_start
ORDER BY period_start ASC

如果记录不存在,如何添加条款if/else。我想让命令返回0并命令返回计数。我不知道这样做。

1 个答案:

答案 0 :(得分:0)

生成缺失数据是一个恼人的问题。通常它最好留给应用程序级别。

如果失败了,如果你在MySQL中这样做,那么缺少的数据必须来自某个地方。这可以是从用户变量和联合交叉连接构建的动态数字序列 - 或者如果我们知道我们的域值(就像我们在这种情况下那样),我们可以预先构建一些表来处理它。

在这种情况下,您需要按日期操作,因此我们需要一些表格来帮助我们生成您感兴趣的所有值。我建议这些表格:

  1. calendar_years(y integer)
  2. calendar_months(m integer)
  3. calendar_days(d integer)
  4. calendar_hours(h integer)
  5. calendar_minutes(m integer)
  6. 这些表格都是一列,包含您正在查看的值范围。 calendar_minutes只能将030作为值,因为我们只看半小时的增量。

    这是cross join实际上是我们想要的实例。

    select unix_timestamp(concat(y, '-', lpad(m, 2, '0'), '-', lpad(d, 2, '0'), ' ', lpad(h, 2, '0'), ':', lpad(mm, 2, '0'), ':', '00')) tt 
      from calendar_years
        cross join calendar_months
        cross join calendar_days
        cross join calendar_hours
        cross join calendar_minutes
    

    现在将为我们提供表格值的所有可能组合,或者实质上 - 我们感兴趣的每个时期。

    我们使用concatlpad将这些列转换为有效的datetime字符串,然后将其转换为unix_timestamp

    这为我们提供了一组与readed_messages联接的价值,这将为您提供最终答案:

    select from_unixtime(tt), count(id)
      from (
        select unix_timestamp(concat(y, '-', lpad(m, 2, '0'), '-', lpad(d, 2, '0'), ' ', lpad(h, 2, '0'), ':', lpad(mm, 2, '0'), ':', '00')) tt
          from calendar_years 
            cross join calendar_months
            cross join calendar_days 
            cross join calendar_hours
            cross join calendar_minutes
      ) q
      left join readed_messages rm
        on (1800 * floor(`date` / 1800)) = q.tt
      where tt <> 0  -- this method is brute force, generates some invalid dates
      group by tt
    

    显然,这会给我们带来很多价值,可能会比您对此感兴趣的时间长得多,如果您愿意,可以在where子句中进一步过滤。

    heres a demo