我使用此查询从预订系统获取统计信息:
SELECT
COUNT(itemid) AS `num_items`,
COUNT(DISTINCT(reservation)) AS `num_reservations`,
CONCAT(MONTHNAME(`from`),' ',YEAR(`from`)) AS `group`
FROM
reserveditems
WHERE
category = 11
AND
( DATE(`from`) >= '2018-01-01' AND DATE(`until`) <= '2018-12-31')
GROUP BY
MONTH(`from`)
这给了我正确的数据,但我还需要得到所有没有结果的月份。
现在我得到了这个结果
"2" "1" "May 2018"
"3" "1" "July 2018"
"11" "8" "October 2018"
"17" "9" "November 2018"
但我需要:
"0" "0" "January 2018"
"0" "0" "February 2018"
"0" "0" "March 2018"
"0" "0" "April 2018"
"2" "1" "May 2018"
"0" "0" "June 2018"
"3" "1" "July 2018"
"0" "0" "September 2018"
"11" "8" "October 2018"
"17" "9" "November 2018"
"0" "0" "December 2018"
不仅如此,daterange还可以由用户编辑,因此他们可能要求从2017年9月到2018年12月的范围,因此从1到12的循环在这里不是一个选项。
统计页面还允许用户按方法决定组,可以是每月、每年或日期。所以如果有一个功能来填充用户选择的所有空白时间段,那就太好了
如果他们询问此数据,则2016年的结果可能为零,如果一个月内没有预订(如周末、节假日……),则一个月内所有日期的结果可能为零
因此,不可能在第二个表中填充所有可能的日期、月份、年份。。。加入这张table。
如果mysql无法实现这个解决方案,我将不得不尝试在php中解决这个问题,但我相信mysql将比另一个循环更快地处理结果(尤其是在按日期分组的情况下)( from
))
谢谢你朝着正确的方向努力!
1条答案
按热度按时间b4wnujal1#
虽然可以创建以0作为条目的临时表,并对现有查询进行联接以获得完整的结果表,但这不是一个好主意。
在系统中,数据库通常是最难扩展的,而应用程序代码则是最简单的。因此,使用应用程序代码来填补结果的空白是对资源的最佳利用。添加包含
YEAR(from)*12 + MONTH(from) - 1
将使应用程序代码很容易检测到漏洞。虽然这是一项额外的工作,但它使用的是相同的行数据,而不是创建一个新表并与之连接。