每个小时每个小时的MySQL计数签名

时间:2017-10-10 19:04:40

标签: mysql sql count case

我是MySQL的新手,所以忍受我潜在的搞砸了。我需要创建一个查询,显示我们不同的成员资格子类型以及每个子类型在给定日期每小时检查的次数。这是我到目前为止所提出的:

SELECT 
 customers.CUSTOMER_CUSTOM_TYPE AS Subtype,
 COUNT(CASE
    WHEN checkins.POSTDATE BETWEEN '%17:00:00' AND '%17:59:59' THEN 1
    ELSE 0
    END) AS '5pm',
 COUNT(CASE
    WHEN checkins.POSTDATE BETWEEN '%18:00:00' AND '%18:59:59' THEN 1
    ELSE 0
    END) AS '6pm',
 COUNT(CASE
    WHEN checkins.POSTDATE BETWEEN '%19:00:00' AND '%19:59:59' THEN 1
    ELSE 0
    END) AS '7pm'
FROM
 checkins,
 customers
WHERE
 checkins.CUSTOMER_ID = customers.CUSTOMER_ID
    AND checkins.POSTDATE LIKE '2017-10-05%'
GROUP BY customers.CUSTOMER_CUSTOM_TYPE;

为了简洁起见,我只包括三个小时。尽管POSTDATE发生了变化,但我每小时都会得到相同的数字。表的设置是正确的:

MySQL Membership Subtype Checkin/Hour

在其他更简单的查询中,我通过计算给定时间范围内的客户CHECKIN_ID来计算签到。每次客户办理入住手续时,都会为客户提供不同的,独特的登记入住身份证。我能正确理解这一点吗?有更简单的方法吗?任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:0)

学习使用正确的join语法。 从不from子句中使用逗号。

查询的简单版本可能是:

SELECT cu.CUSTOMER_CUSTOM_TYPE AS Subtype,
       SUM( hour(ch.POSTDATE) = 17) AS `5pm`,
       SUM( hour(ch.POSTDATE) = 18) as `6pm`,
       SUM( hour(ch.POSTDATE) = 19) as `7pm`
FROM checkins ch JOIN
     customers cu
     ON ch.CUSTOMER_ID = cu.CUSTOMER_ID
WHERE DATE(ch.POSTDATE) = '2017-10-05'
GROUP BY cu.CUSTOMER_CUSTOM_TYPE;

注意:

  • 使用表别名。它们使查询更容易编写和阅读。
  • 不要对日期和时间使用字符串比较。这将提取比较日期(如果您在该列上有索引,则有其他选项)。
  • LIKE模式不适用于BETWEEN。我用更简单的HOUR()替换它。
  • 这使用MySQL快捷方式将布尔表达式视为数字上下文中的数字 - 因此不需要case

答案 1 :(得分:0)

如果您不太关注当前表的结构,我是否可以建议重新设计数据结构,这可能会大大简化此信息。

您似乎正在尝试跟踪三个关键信息点:customer_idroomcheck_in_time。那么,您提到的checkin_id可能是插入此表时生成的PRIMARY KEY值。首先,不要将这些信息按时间排序到类似于图表的表格中,只需跟踪这三个数据就很有价值。

接下来,而不是很多情况:看一下使用GROUP BY语句。在需要按房间划分的情况下,那么小时看起来会像这样:

SELECT count(*) as num, hour(check_in_time) as hr
FROM checkins
Group By room, hr

这将在所有时间返回所有房间每小时的登记计数。如果您希望按日或年分解,只需将时间函数添加到Select和Group语句中。