【问题标题】:SQL query to count the number of rows in different columns with group by clausesSQL查询使用group by子句计算不同列中的行数
【发布时间】:2020-09-17 19:00:28
【问题描述】:

在我的 Mysql 数据库中,我有 2 列分别存储进程的开始日期和结束日期。我需要编写一个查询,允许我计算每个月在每列中的行数,并分别显示计数。

表格示例:

+----+------------+----------------+
| id | startData  |     endData    |
+----+-------------+----------------+
|  1 | 02/03/2020 |    02/03/2020  | 
|  2 | 02/04/2020 |    02/04/2020  |
|  3 | 02/04/2020 |    02/05/2020  |
|  4 | 02/04/2020 |    02/05/2020  |
|  5 | 02/05/2020 |    02/06/2020  |
|  6 | 02/05/2020 |    02/06/2020  |
|  7 | 02/06/2020 |    02/07/2020  |
+----+-------------+----------------+

我想要结果:

+-------+--------------------+-------------------+
| month |  count_month_start |  count_month_end  |
+-------+--------------------+-------------------+
|  03   |         01         |          01       |
|  04   |         03         |          01       |
|  05   |         02         |          02       |
|  06   |         01         |          02       |
|  07   |         00         |          01       |
+-------+--------------------+-------------------+

【问题讨论】:

  • 请给我们查询以填充数据,您可以使用sqlfiddle.com 来完成此操作
  • 您的数据与默认的 MySQL 日期时间数据格式不匹配。编辑您的示例。
  • 你试过什么吗???如果没有,请开始工作。

标签: mysql sql


【解决方案1】:

假设您的开始日期和结束日期列的数据类型为日期,您可以这样做 -

Select ifnull(Tb1.mn,Tb2.mn) As mn, ifnull(count_mn_start,0) As count_mn_start, ifnull(count_mn_end,0) As count_mn_end
 from
 (Select Month(StartDate) as mn, count(id) as count_mn_start
  from
  my_table
 Group by Month(StartDate))Tb1
 left Join (Select Month(EndDate) as mn, count(id) as count_mn_end
  from my_table
  Group by Month(EndDate)) Tb2
  on Tb1.mn = Tb2.mn
UNION
 Select ifnull(Tb1.mn,Tb2.mn) As mn, ifnull(count_mn_start,0) As count_mn_start, ifnull(count_mn_end,0) As count_mn_end
 from
 (Select Month(StartDate) as mn, count(id) as count_mn_start
  from
  my_table
 Group by Month(StartDate))Tb1
 Right Join (Select Month(EndDate) as mn, count(id) as count_mn_end
  from my_table
  Group by Month(EndDate)) Tb2
  on Tb1.mn = Tb2.mn;

DB 小提琴 - https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=84ecddb9f5ed431ddff6a9eaab87e5df

PS:如果您的日期只有一年(以 2020 年为例),这将起作用,但理想情况下,如果数据中有不同的年份,请考虑在输出中也包含年份,在这种情况下使用相同的语法即 Year(datefield) 并将其添加到子查询中的 select 和 group by 中(与上述查询中的月份相同)。

【讨论】:

  • 您的回答与所要求的不符。使用 Join 子句,仅组合两个计数都显示结果的结果(count_mn_star、count_mn_end)。如果在一个月内,其中一个计数等于 0,则结​​果不会出现在决赛桌中。例如:如果我在 6 月份启动了 3 个进程,而本月没有完成任何进程,则不会出现 [June :( 3 | 0)] 行。如果您知道解决方案,请更正代码。
  • 感谢举报!我已经编辑了查询,并且还在响应中提供了一个 db fiddle 链接。由于 MySQL 不允许完全外连接,因此该方法变得复杂,为了克服我不得不对左右外集进行联合,
【解决方案2】:

一种非常简单的方法是使用递归 CTE 将时间段扩展为天。然后聚合:

with recursive cte as (
      select id, startdate as dte, enddate
      from t
      union all
      select id, dte + interval 1 day, enddate
      from cte
      where dte < enddate
     )
select year(dte), month(dte),
       sum( day(dte) = 1 ) as cnt_start,
       sum( day(dte) = day(last_day(dte)) ) as cnt_end
from cte
group by year(dte), month(dte) ;

Here 是一个 dbfiddle。

【讨论】:

    猜你喜欢
    • 2022-11-02
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多