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 - 选择具有默认值的期间的数据的主要内容,如果未能解决你的问题,请参考以下文章
ODataActionParameters 具有具有默认值的属性