使用“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 自加入以获取日期范围和计数?