如何使用两个日期和BETWEEN更新查询以计算SUM或COUNT?

时间:2019-06-07 21:37:41

标签: mysql sql

我当前的查询是这样的

     SELECT
      CAST(COUNT(`MID`) AS UNSIGNED) AS Y,
      CONCAT(
          LEFT(MONTHNAME(`date`),
          3),
          ' ',
          YEAR(`date`)
      ) AS label
  FROM
      `reservations`
  WHERE
      `MID` = 22 AND YEAR(`date`) = YEAR(CURDATE())
  GROUP BY
      CONCAT(
          LEFT(MONTHNAME(DATE),
          3),
          ' ',
          YEAR(`date`)
      ),
      YEAR(DATE),
      MONTH(DATE)
  ORDER BY
      YEAR(`date`),
      MONTH(`date`) ASC

它产生以下结果,我们在Google图表中使用这些结果来显示每月的预订数量。 问题是,我们只获得创建预订的次数,而不是开始日期(日期)和结束日期(dateLast)之间的天数。

 Y      label
 ________________
 22      Feb 2019
 28      Mar 2019
 15      Apr 2019
 3       May 2019
 5       Jun 2019
 2       Jul 2019
 1       Aug 2019
 1       Oct 2019
 2       Nov 2019
 9       Dec 2019

我一直在尝试以下更新,但遇到与BETWEEN运算符有关的错误:

 SELECT
     CAST(COUNT(`mid`) AS UNSIGNED BETWEEN `date` AND `dateLast`) AS D, CONCAT(
         LEFT(MONTHNAME(DATE),
         3), ' ',  YEAR(DATE) ),
     CAST(COUNT(`mid`) AS UNSIGNED) AS Y,
     CONCAT(
         LEFT(MONTHNAME(DATE),
         3),
         ' ',
         YEAR(DATE)
     ) AS label
 FROM
     `reservations`
 WHERE
     `mid` = 22 AND YEAR(DATE) = YEAR(CURDATE())
 GROUP BY
     CONCAT(
         LEFT(MONTHNAME(DATE),
         3),
         ' ',
         YEAR(DATE)
     ),
     YEAR(DATE),
     MONTH(DATE)
 ORDER BY
     YEAR(DATE),
     MONTH(DATE) ASC

MySQL说:文档

您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在第2行的'BETWEEN datedateLast)AS D,CONCAT(LEFT(MONTHNAME(DATE),')AS

目标是获取AND之间(包括datedateLast之间的所有保留天数的总和。注意:dateLast由于其结帐日期而未被计入。也许这对于SQL查询来说太复杂了,应该在PHP中作为一系列子例程来处理?

2 个答案:

答案 0 :(得分:1)

SQL绝对可以解决这个问题。使用DATEDIFF函数 https://www.w3schools.com/sql/func_mysql_datediff.asp

答案 1 :(得分:1)

如果您不需要将一个预订的天数划分为多个月,则只需使用SUM(DATEDIFF(dateLast,date))

select year(date) y, month(date) m, sum(datediff(dateLast, date)) c
from reservations
group by y, m
order by y, m

db-fiddle

如果您想拆分它们,那么我希望您的版本(MySQL 8+或MariaDB 10.2+)支持递归查询。在这种情况下,您可以将日期范围扩大到该范围中的每天一行,并对其进行计数:

with recursive rcte as (
  select date, dateLast 
  from reservations
  where dateLast > date -- optional
  union all
  select rcte.date + interval 1 day, rcte.dateLast
  from rcte
  where rcte.date < rcte.dateLast - interval 1 day
)
  select year(date) y, month(date) m, count(*) c
  from rcte
  group by y,m
  order by y,m

db-fiddle