2013-08-28 50 views
0

我想列出具有特定事件計數的用戶,但我對使用哪種方法感到困惑。MySQL - 正確的方法事件計數

這是數據庫表:

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,但它實際上名單觀衆2太不具備PURCHASE_HOTEL事件。如你所想,會有更多的「規則」像每個特定案例的所有JOIN事件一樣。我們可以糾正和改進這種方式嗎?

獎勵: 這種方法的名稱是什麼?

回答

1

我認爲這是一個「set-set-set」查詢。我喜歡用這種查詢類型的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記錄數和當至少一個發現是真的。 (如果您只需要一個,請將> 0更改爲= 0。)

第二個條件檢查查看酒店頁面。

第三個數字是酒店購買的數量。

+0

非常感謝。我會玩這個。我應該繼續閱讀什麼來了解更多關於這種技術的知識?我應該閱讀關於「有」嗎? – Herr

+0

@赫爾克。 。 。理解'group by'和'having'是從哪裏開始的。這在使用它們時是微妙的。然而,一些練習值得大量學習。 –

+0

有關此主題的任何好書建議先生? – Herr