SQL - 选择具有默认值的期间的数据

Posted

技术标签:

【中文标题】SQL - 选择具有默认值的期间的数据【英文标题】:SQL - Select data on a period with a default value 【发布时间】:2016-05-24 19:54:06 【问题描述】:

我想从表格中选择数据,在 javascript 中获取结果并将其打印在图表中(x = 日期,y = 数字)

我有以下DATA 表(注意:我尝试将其放入 Markdown 中,使其显示为 html 表,但似乎不起作用):

| date    | number |
|---------|--------|
| 2015-01 | 12     |
| 2015-02 | 7      |
| 2015-04 | 4      |

和下面的 SQL 选择:

SELECT date_format(date, '%Y-%m') AS date, number
FROM DATA
WHERE date >= '2015-01' AND date <= '2015-05'
GROUP BY date
ORDER BY date;

这给了我与输出完全相同的表。但是,如果没有记录该月份,我想要的是每个月使用0 进行一行。比如数据库中没有记录三月,所以我想要的结果:

| date    | number |
|---------|--------|
| 2015-01 | 12     |
| 2015-02 | 7      |
| 2015-03 | 0      |
| 2015-04 | 4      |
| 2015-05 | 0      |

表格转到 5 月,因为在 SELECT 中我希望在 1 月和 5 月之间的每个月。

问题是:有没有办法在 SQL 中做到这一点,还是我必须在 JavaScript 中对结果进行后处理才能在我的最终表格中添加空月份?

感谢您的帮助


edit:开始和结束日期是可变的,可以涵盖数年。所以,我想可以用一个包含月份的特殊表格来做一些事情,但我不知道如何...... 如果答案是后期处理,那没关系(令人失望但还可以^^)


edit2:问题是@mauro 所说的“填补空白”。它在 mysql 中看起来很复杂,所以我要对我的请求进行后处理。

见How to fill date gaps in MySQL?

【问题讨论】:

【参考方案1】:

我将创建第二个表DATA2每月一行,数字=零。然后,而不是选择:

FROM DATA

我会选择:

FROM ( SELECT * FROM DATA UNION ALL SELECT * FROM DATA2 ) D

这样...如果 DATA 包含给定月份的值,您将从 DATA 获得总计,如果不...您将从 DATA2 获得零

【讨论】:

这是一个想法。问题是开始和结束日期是可变的,可以涵盖几年:/我正在编辑我的问题我希望 SQL 有一种可以实现我的愿望的日期计算器...... @Rémi 使用其他数据库 - 具有“填补空白”功能 - 这会更容易,而且不会那么“粗鲁”:-) “填补空白”!使用正确的关键字,我会得到更好的搜索结果 :) ***.com/questions/1877874/… 似乎在 MySQL 中它很复杂,所以我想我要进行后期处理,因为为此创建一个临时表看起来非常难看.. .但我不知道什么是最好的性能。谢谢!【参考方案2】:

这是一个没有临时表的示例。它使用序列引擎。唯一的区别是您必须填写开始日期和月数 (seq_0_to_4)。

SELECT `DATE`, SUM(number) as number
FROM (
  SELECT
    date_format( IF(d.`DATE` IS NULL, init.`DATE`, d.`DATE`) ,'%Y-%m') AS `DATE`
    , IF(d.number IS NULL,0,d.number) as number
  FROM (
    SELECT '2015-01-01' + INTERVAL seq MONTH AS `DATE`, 0 AS number
    FROM seq_0_to_4
    ) AS INIT
  LEFT JOIN DATA d ON date_format(d.`DATE`,'%Y-%m') = date_format( init.`DATE` ,'%Y-%m')
  ) AS result
GROUP BY `DATE`
ORDER BY `DATE`;

结果

+---------+--------+
| DATE    | number |
+---------+--------+
| 2015-01 |      7 |
| 2015-02 |      0 |
| 2015-03 |      7 |
| 2015-04 |      0 |
| 2015-05 |      0 |
+---------+--------+
5 rows in set (0.00 sec)

表格

MariaDB > select * from data;
+------------+--------+
| date       | number |
+------------+--------+
| 2015-01-01 |      4 |
| 2015-01-02 |      3 |
| 2015-03-05 |      7 |
+------------+--------+
3 rows in set (0.00 sec)

MariaDB >

【讨论】:

这可能有效,但不幸的是特定于 MariaDB。 MySQL中不存在序列引擎,仅在MariaDB 10+中...所以,我将原帖保持原样(edit2解释问题来自MySQL缺乏功能)。如果可以的话,我会安装 MariaDB,但它是针对现有解决方案的……我只是在您的请求中有一个问题:您有IF(d.number IS NULL,0,d.number),然后您在INIT 中选择0 AS number。我想这不是必需的,因为您之前直接在IF 中使用了0,对吧? 是的,对不起。您可以删除 0 作为数字。我的错误

以上是关于SQL - 选择具有默认值的期间的数据的主要内容,如果未能解决你的问题,请参考以下文章

XML反序列化处理具有默认值的空标签

sql语句中修改字段的默认值,该怎么做

ODataActionParameters 具有具有默认值的属性

LINQ to SQL 默认值

SQL如何使用 alter column语句添加字段的默认值(defualt)?

从 parquet 文件将具有默认值的数据加载到 Redshift