MySQL - 拥有和总结2个不同的表

时间:2013-08-28 14:19:17

标签: mysql group-by having

这是https://stackoverflow.com/questions/18487327/mysql-correct-approach-event-counting

的后续问题

这是数据库表:

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);

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

INSERT INTO `attribute` (`attribute_id`, `visitor_id`, `key`, `value`, `label`, `datetime`)
VALUES
    (1, 1, 'TITLE', 'Professor', '', NULL);

我正在运行以下查询:

SELECT
    `e`.`visitor_id`
FROM 
    `event` e,
    `attribute` a
GROUP by 
    `e`.`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
AND sum(a.key = 'TITLE' and a.value = 'Professor') > 0

我希望只返回带有TITLE ='Professor'属性的访问者(1),但不知怎的,查询给了我两个访问者。

  • 我在这里做错了什么,以便两个用户都被退回?
  • 如果他的条件不匹配(TITLE ='教授'),我附加所有条件“AND”不应该排除访客2吗?

1 个答案:

答案 0 :(得分:2)

您没有加入这两个表:

SELECT
    `e`.`visitor_id`
FROM 
    `event` e join
    `attribute` a
    e.visitor_id = a.visitor_id
GROUP by 
    `e`.`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
AND sum(a.key = 'TITLE' and a.value = 'Professor') > 0;

使用cross join(您的原始配方),所有属性都适用于所有事件。因此,所有事件都符合标准。