MySQL计数每个会员每个小时的签到次数
问题描述:
我是MySQL的新手,请耐心等待我的潜在问题。我需要创建一个查询来显示我们不同的成员子类型以及每个子类型在给定日期每小时签入的次数。这是我到目前为止: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数签入。每次登记时,客户都会得到不同的唯一登记ID。我是否正确地进行了此操作?有一种更简单的方法吗?任何帮助表示赞赏!
答
学习使用正确的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
。
答
如果你不太依附当前表格的结构,我可能会建议重新设计数据结构,这可能会大大简化这些信息。
看起来您似乎试图追踪三个关键信息点:customer_id
,room
和check_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语句中即可。
'COUNT()'应该是'SUM()'。 – Barmar