使用“where”在数据库上获取“计数”以设置日期限制

Posted

技术标签:

【中文标题】使用“where”在数据库上获取“计数”以设置日期限制【英文标题】:Get a "count" on a database using "where" to set a limit on the date 【发布时间】:2017-10-12 01:30:45 【问题描述】:

我有一个数据库,其中有一个表格来保存报告。每个报告都有一个日期(年-月-日),在创建报告时设置。

经过大量测试,我得到了一些工作,但不是我希望它工作。

我想获取从初始日期(年-月-日)到最终日期(年-月-日)每个月生成的报告数量。但我不太确定如何完成它。

这是我现在使用的 MySQL 语句:

SELECT meses.month id_mes, count(re_fecha) total
       FROM
       (
               SELECT 1 AS MONTH
                  UNION SELECT 2 AS MONTH
                  UNION SELECT 3 AS MONTH
                  UNION SELECT 4 AS MONTH
                  UNION SELECT 5 AS MONTH
                  UNION SELECT 6 AS MONTH
                  UNION SELECT 7 AS MONTH
                  UNION SELECT 8 AS MONTH
                  UNION SELECT 9 AS MONTH
                  UNION SELECT 10 AS MONTH
                  UNION SELECT 11 AS MONTH
                  UNION SELECT 12 AS MONTH

       ) as meses

LEFT JOIN reportes ON month(re_fecha)  = meses.MONTH
WHERE re_fecha BETWEEN '2017-01-01' AND '2017-08-31'
GROUP BY meses.MONTH, monthName(re_fecha)

这是我使用 MySQL 语句得到的以下结果:

id_mes  | total
---------------
  04    | 15
  05    | 5 
  06    | 15
  07    | 2

我不确定这是否有任何帮助,但如果我不使用“where re_fechas...”,我会得到更接近我们所寻找的结果:

id_mes  | total         
-------------           
01      | 0         
02      | 0         
03      | 0         
04      | 15            
05      | 5
06      | 15
07      | 2
08      | 6
09      | 0
10      | 0
11      | 0
12      | 0

最后,我想看看:

id_mes       | total            
-------------------     
01-2017      | 0            
02-2017      | 0             
03-2017      | 0            
04-2017      | 15
05-2017      | 5
06-2017      | 15
07-2017      | 2
08-2017      | 6

我现在的工作方式有两个问题:

    当我使用句子“where”时,在指定日期有 0 个报告的月份不会显示。如果我不使用“where”,我会以我想要的方式得到东西,但不是在我想要的日期范围内。

    我遇到的另一个问题是我想获取月份中的年份(如上面所需的代码块所示)。

我希望这是足够的信息来理解一切,我不确定我是否可以提供数据库,但如果你认为这会有所帮助,请告诉我。

【问题讨论】:

【参考方案1】:

你几乎明白了。

如果您将OR re_fecha IS NULL 添加到您的WHERE 子句中,那么您几乎可以得到您想要的。

我想出了另一个可以帮助您的解决方案:

SELECT meses.aMonth aMonth, COUNT(re_fecha) total
FROM (
  -- Listing all months in period
  SELECT DATE_FORMAT(m1, '%m-%Y') aMonth
  FROM (
    -- Range limit: about 21 years
    SELECT
    ('2017-01-01' - INTERVAL DAYOFMONTH('2017-01-01')-1 DAY) +INTERVAL m MONTH as m1
    FROM (
      SELECT @rownum:=@rownum+1 m FROM
      (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t1,
      (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t2,
      (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t3,
      (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t4,
      (SELECT @rownum:=-1) t0 ) d1
    ) d2 
  WHERE m1 <= '2017-08-31'
  ORDER BY m1) meses
LEFT JOIN reportes ON DATE_FORMAT(re_fecha, '%m-%Y') = meses.aMonth
WHERE re_fecha BETWEEN '2017-01-01' AND '2017-08-31'
OR re_fecha IS NULL
GROUP BY meses.aMonth;

测试一下:http://sqlfiddle.com/#!9/d21de6/27

示例输出:

aMonth    total
01-2017   0
02-2017   0
03-2017   0
04-2017   15
05-2017   5
06-2017   0
07-2017   2
08-2017   0

如果您没有使用 mysql,那么您可以使用 FULL OUTER JOIN 而不是 LEFT JOIN

请注意,此解决方案的有效期为 21 年。尝试仅将初始日期更改为 1970 年并亲自查看。 如果需要,请添加更多 (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) tn, 以增加月数。

参考和有用的链接:

MySQL monthly Sale of last 12 months including months with no SaleHow to get a list of months between two dates in mysqlHow to do a FULL OUTER JOIN in MySQL?

【讨论】:

@Strawberry 尽管这很费力,但如果 OP 不需要可变的月份范围,这很简单。虽然我们需要 FULL OUTER JOIN,但我们在 MySQL 上没有它,所以我们需要用 LEFT JOIN 模拟它。我更新了我的答案,添加了另一种解决此问题的方法。 明白了——我的错误。 这很完美!我们已经对其进行了尝试并实施了它,并且它正在按照我们的意愿运行。我很感激你的回复。谢谢你们。【参考方案2】:

在您的查询中尝试将 WHERE 更改为 AND。

【讨论】:

以上是关于使用“where”在数据库上获取“计数”以设置日期限制的主要内容,如果未能解决你的问题,请参考以下文章

Oracle:有效地使用where子句过滤时间戳列以获取特定日期的所有记录

7 天用户计数:Big-Query 自加入以获取日期范围和计数?

有没有办法在 python 中使用数据集中的变量计数以日期作为预测变量来运行线性回归?

日期字段上的左连接 + Where 子句

跳出查询以在存储过程中从单独的表中获取 where 子句

如何使用 SQL 获取 2 列之间日期差异的计数(值的分布)?