MySQL在结果集中添加缺少的月份

Posted

技术标签:

【中文标题】MySQL在结果集中添加缺少的月份【英文标题】:MySQL Add missing Months in resultset 【发布时间】:2020-01-09 22:05:26 【问题描述】:

我正在尝试在此结果集中添加缺失的月份。

如果缺少月份,请将其添加为 Quantita 值 0。

SELECT MONTH(Data) AS Mese,Count(*) AS Quantita 
FROM prenotazioni 
WHERE Cancellata IS NULL 
AND FKCampo = 1 
AND YEAR(Data) = YEAR(CURDATE()) -1 
GROUP BY Mese 
ORDER BY Mese ASC 


+------+----------+
| Mese | Quantita |
+------+----------+
| 4    | 123      |
+------+----------+
| 5    | 100      |
+------+----------+
| 7    | 377      |
+------+----------+
| 9    | 54       |
+------+----------+

【问题讨论】:

考虑处理应用代码中数据显示的问题 什么版本的 mysql 【参考方案1】:

以下是混乱的,我相信必须有一个更清洁的方式......

所以,首先我创建一个包含所有月份的表:

CREATE TABLE all_months (
 month_num INT
);

INSERT INTO all_months VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)

然后我将您的查询与此表(在我的情况下在右侧)结合起来,并使用 case-when 来确定是否有计数:

SELECT 
  all_months.month_num, 
  CASE 
    WHEN tmp.Quantita is NULL THEN 0 
    ELSE tmp.Quantita 
  END as Quantita
FROM (
  SELECT MONTH(Data) AS Mese,Count(*) AS Quantita 
  FROM prenotazioni 
  WHERE Cancellata IS NULL 
  AND FKCampo = 1 
  AND YEAR(Data) = YEAR(CURDATE()) -1 
  GROUP BY Mese 
 ) as tmp
RIGHT JOIN all_months on all_months.month_num=tmp.Mese
ORDER BY all_months.month_num ASC

您的查询现在在tmp 中,之后正在订购。结果是:

month_num   Quantita
1           1
2           2
3           0
4           0
5           0
6           0
7           0
8           3
9           1
10          0
11          1
12          1

演示:here

【讨论】:

【参考方案2】:

一种方法是构建或查找包含您想要的所有月份的表并使用LEFT JOIN

不过,在您的情况下,条件聚合可能会使用更简单的查询来完成此操作。这假设您每个月至少有一行,即使已被现有的 where 子句过滤掉。

所以,这可能有效:

SELECT MONTH(Data) AS Mese,
       SUM(Cancellata IS NULL AND FKCampo = 1 ) AS Quantita 
FROM prenotazioni 
WHERE YEAR(Data) = YEAR(CURDATE()) - 1 
GROUP BY Mese 
ORDER BY Mese ASC ;

当然,如果原始表中没有所有月份,那么它们仍然不会出现在结果集中,而您又不得不使用外连接。

【讨论】:

【参考方案3】:

与@urban 的想法相同,但使用左连接简化了查询:

create table prenotazioni
    (
        id int auto_increment,
        Cancellata int  default null null,
        FKCampo    int  default 1    null,
        Data       date default null null,
        constraint table_nametes_pk
            primary key (id)
    );

    insert into prenotazioni (Cancellata, FKCampo, Data)
    values (null, 1, "2019-04-01"),
           (null, 1, "2019-04-01"),
           (null, 1, "2019-05-01"),
           (null, 1, "2019-05-01"),
           (null, 1, "2019-05-01"),
           (null, 1, "2019-01-01"),
           (null, 1, "2019-01-01"),
           (null, 1, "2020-01-01"),
           (null, 1, "2018-01-01");

    CREATE TABLE all_months (
     month_num INT
    );

    INSERT INTO all_months VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);

    select month_num, count(p.Data)
    from
        all_months am left join prenotazioni p on (am.month_num = month(p.Data))
    where
        p.id is null
       or
      (Cancellata IS NULL AND FKCampo = 1 AND YEAR(Data) = YEAR(CURDATE()) - 1)
    GROUP BY am.month_num
    ORDER BY am.month_num;

结果:

【讨论】:

提供预期的输入和输出比拒绝那些花时间帮助你的人更有帮助。

以上是关于MySQL在结果集中添加缺少的月份的主要内容,如果未能解决你的问题,请参考以下文章

java - 如何在Java中从MySQL结果集中的while循环中添加值?

MYSQL 的查询结果集中怎样从最后一个倒过来取

如何在 MySQL 中对两个结果集中的列求和

PHP mysql_num_rows() 函数 返回结果集中行的数目。

MySQL数据库:合并结果集

遍历 Nodejs MySQL 结果集中的字段