MySQL - 正确的事件计数方法

标签 mysql join subquery self-join

我想列出具有特定事件计数的用户,但我对采取哪种方法感到困惑。

这是数据库表:

CREATE TABLE `event` (
  `event_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `visitor_id` int(11) DEFAULT NULL,
  `key` varchar(200) DEFAULT NULL,
  `value` text,
  `label` varchar(200) DEFAULT '',
  `datetime` datetime DEFAULT NULL,
  PRIMARY KEY (`event_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;


INSERT INTO `event` (`event_id`, `visitor_id`, `key`, `value`, `label`, `datetime`)
VALUES
    (1, 1, 'LOGIN', NULL, '', NULL),
    (2, 2, 'LOGIN', NULL, '', NULL),
    (3, 1, 'VIEW_PAGE', 'HOTEL', '', NULL),
    (4, 2, 'VIEW_PAGE', 'HOTEL', '', NULL),
    (5, 1, 'PURCHASE_HOTEL', NULL, '', NULL);

CREATE TABLE `visitor` (
  `visitor_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `datetime` datetime DEFAULT NULL,
  PRIMARY KEY (`visitor_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

INSERT INTO `visitor` (`visitor_id`, `datetime`)
VALUES
    (1, NULL),
    (2, NULL);

这是我的方法:

SELECT DISTINCT
    t1.`visitor_id`
FROM
    `visitor` t1

JOIN `event` t2 on t1.visitor_id = t2.visitor_id AND t2.`key` = 'LOGIN'
JOIN `event` t3 on t1.visitor_id = t3.visitor_id AND t3.`key` = 'VIEW_PAGE' AND t3.`value` = 'HOTEL'
WHERE ( SELECT COUNT(*) FROM `event` WHERE `event`.`key` = 'PURCHASE_HOTEL' ) > 0

这应该只列出访客 1,但实际上也列出了没有 PURCHASE_HOTEL 事件的访客 2。

正如您可以想象的那样,将会有更多的“规则”,例如每个特定情况的所有 JOIN 事件。我们能以某种方式纠正和改进这个问题吗?

奖金: 这种方法的名称是什么?

最佳答案

我认为这是一个“集合内集合”查询。对于此类查询,我喜欢使用带有 having 子句的聚合。以下检查您正在寻找的三个条件:

select visitor_id
from event e
group by visitor_id
having sum(e.key = 'LOGIN') > 0 and
       sum(e.key = 'VIEW_PAGE' and e.value = 'HOTEL') > 0 and
       sum(e.key = 'PURCHASE_HOTEL') > 0;

having 子句中的第一个条件计算 LOGIN 记录的数量,并且当至少找到一个时为 true。 (如果您只想要一个,请将 > 0 更改为 = 0。)

第二个条件检查酒店页面的查看情况。

第三个统计的是酒店购买的数量。

关于MySQL - 正确的事件计数方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18487327/

相关文章:

php - 连接两个表但每个表中记录数不同的问题

mysql - 主/外键;使用子查询连接多个表

java - MySQL 数据库服务器对比phpmyadmin

Python mysql 连接器 LIKE 针对 unicode 值

mysql - 具有复杂 'if/else' 要求的 SQL SELECT 语句

javascript - 循环中 PHP 数组到 Javascript

mysql - 使用 JOIN 条件限制 SQL JOIN

python - 在 sqlalchemy 中外部连接两个表时按问题排序

nested - Firebase 嵌套查询

mysql - 从具有 2 个条件的表中删除不需要的行