首页 > 解决方案 > 如何从 MySQL 中选择一个月内但日期可能在下个月的所有行?

问题描述

我有一张看起来像这样的桌子;

ID | netID | indate             | outdate           | name    | org
=====================================================================
1  |  50   | 2020-03-31 23:50   | 2020-03-31 23:32  | Bill    | orgA
2  |  50   | 2020-03-31 23:51   | 2020-03-31 23:32  | Fred    | orgA
3  |  50   | 2020-04-01 00:02   | 2020-04-01 00:05  | Sam     | orgA

4  |  51   | 2020-03-31 23:50   | 2020-03-31 23:32  | Harry   | orgB    
5  |  51   | 2020-03-31 23:51   | 2020-03-31 23:32  | George  | orgB
6  |  51   | 2020-04-01 00:02   | 2020-04-01 00:05  | Tom     | orgB

我需要按组织和年月编写报告,但是必须包含具有相同 netID 的任何行,即使它在不同的年份或月份。例如,我不能说“WHERE netID = 50”,因为我不知道“2020”年“03”月的“netID”是什么。

如果我需要 orgA 的 2020 年 3 月报告,我正在寻找要返回的前三行。

下面不适用于我需要的东西,而且我不知道如何获取每个 netID 的所有行,无论月份如何。有人可以给我一个如何检索它们的例子吗?

SELECT date(iodate) as logdate,
       Name,
       netID,
       COALESCE( netID, 'Month Total') AS netTTL,
       COUNT(ID) AS idCount,
       month(logdate AS month    
  FROM table
 WHERE org = 'orgA'
   AND year(indate) = '2020'
   AND month(iodate) = '03'
 GROUP BY year(logdate), month, netID WITH ROLLUP

标签: mysql

解决方案


获取存在任何行的所有行的一种方法,该行具有相同的网络 ID、请求的组织和请求范围内的日期,是在派生表中获取范围和组织的网络 ID,然后加入该表。

SELECT t1.*
       FROM (SELECT DISTINCT
                    t2.netid
                    FROM elbat t2
                    WHERE t2.org = 'orgA'
                          AND t2.indate >= '2020-03-01'
                          AND t2.indate < '2020-04-01') x
            INNER JOIN elbat t1
                       ON t1.netid = x.netid;

几点注意事项:

  • 您应该使用范围表达式,而不是将year()and应用于子句month()中的日期。WHERE范围表达式可以使用索引并加快查询速度。
  • 在您的查询中,您的列/表达式既不应用于聚合函数,也不应用于GROUP BY. 尽管旧的或配置错误的 MySQL 服务器接受了这一点,但它可能会产生有趣的结果。但是由于你没有进一步解释你想在那里做什么,所以这里没有什么比“你做错了!”更多的东西。

推荐阅读