我有一张名为log
的表。
表: log
ID user_id time_of_action
我想为每个用户获取每个日期i.e.
group by date,user_id
的结果。
所以,这是预期的输出结构:
user_id date occurred_in_afternoon occurred_at_night total_action_count
解释
happen_in_afternoon:用户的任何操作是否发生在12:00 PM
到4:00 PM
之间
happen_at_night:是否在8:00 PM
到12:00 AM
(第二天)之间发生了任何用户操作
架构和示例数据:
DROP TABLE IF EXISTS `logs`;
CREATE TABLE `logs` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`time_of_action` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`Id`)
);
INSERT INTO `logs` VALUES ('1', '71', '2016-03-10 10:07:34');
INSERT INTO `logs` VALUES ('2', '66', '2016-03-10 14:07:57');
INSERT INTO `logs` VALUES ('3', '71', '2016-03-10 22:08:27');
INSERT INTO `logs` VALUES ('4', '71', '2016-03-10 15:08:40');
这是我目前的疑问:
SELECT
user_id,
DATE(time_of_action) `date`,
CASE WHEN time_of_action BETWEEN TIMESTAMPADD(HOUR,12,DATE(time_of_action)) AND TIMESTAMPADD(HOUR,16,DATE(time_of_action)) THEN 1 ELSE 0 END occurred_in_afternoon,
CASE WHEN time_of_action BETWEEN TIMESTAMPADD(HOUR,20,DATE(time_of_action)) AND TIMESTAMPADD(HOUR,24,DATE(time_of_action)) THEN 1 ELSE 0 END occurred_at_night,
COUNT(*) total_action_count
FROM `logs`
GROUP BY `date`,user_id
我目前的输出:
user_id date occurred_in_afternoon occurred_at_night total_action_count
66 2016-03-10 1 0 1
71 2016-03-10 0 0 3
预期输出:
user_id date occurred_in_afternoon occurred_at_night total_action_count
66 2016-03-10 1 0 1
71 2016-03-10 1 1 3
问题是我没有得到预期的结果。我想下午发生的值会被另一个time_of_action重置,而这个时间不在那个下午的区域。 是否可以在单个查询中实现它?
答案 0 :(得分:1)
您错过了使用聚合函数。您可以将MAX()
或BIT_OR()
用于您的目的:
SELECT
user_id,
DATE(time_of_action) `date`,
MAX(CASE WHEN time_of_action BETWEEN TIMESTAMPADD(HOUR,12,DATE(time_of_action)) AND TIMESTAMPADD(HOUR,16,DATE(time_of_action)) THEN 1 ELSE 0 END) occurred_in_afternoon,
MAX(CASE WHEN time_of_action BETWEEN TIMESTAMPADD(HOUR,20,DATE(time_of_action)) AND TIMESTAMPADD(HOUR,24,DATE(time_of_action)) THEN 1 ELSE 0 END) occurred_at_night,
COUNT(*) total_action_count
FROM `logs`
GROUP BY `date`,user_id
更新:我还希望使用更易阅读的版本,例如
SELECT
user_id,
DATE(time_of_action) `date`,
BIT_OR(TIME(time_of_action) BETWEEN '12:00:00' AND '16:00:00') occurred_in_afternoon,
BIT_OR(TIME(time_of_action) BETWEEN '20:00:00' AND '23:59:59') occurred_at_night,
COUNT(*) total_action_count
FROM `logs`
GROUP BY `date`,user_id
答案 1 :(得分:0)
我正在考虑使用SUM
获得的结果表的别名,以便为这两个字段获取Binary value
。
SELECT
t.user_id,
t.date,
CASE WHEN t.occurred_in_afternoon > 0 THEN 1 ELSE 0 END AS occurred_in_afternoon,
CASE WHEN t.occurred_at_night > 0 THEN 1 ELSE 0 END AS occurred_at_night,
t.total_action_count
FROM
(SELECT
user_id,
DATE(time_of_action) `date`,
SUM(CASE WHEN time_of_action BETWEEN TIMESTAMPADD(HOUR,12,DATE(time_of_action)) AND TIMESTAMPADD(HOUR,16,DATE(time_of_action)) THEN 1 ELSE 0 END) occurred_in_afternoon,
SUM(CASE WHEN time_of_action BETWEEN TIMESTAMPADD(HOUR,20,DATE(time_of_action)) AND TIMESTAMPADD(HOUR,24,DATE(time_of_action)) THEN 1 ELSE 0 END) occurred_at_night,
COUNT(*) total_action_count
FROM `logs`
GROUP BY `date`,user_id) t