2012-09-12 137 views
4

所以我試圖計算我的系統中每個餐廳的重複訂單數量。這被定義爲已經從該餐館多次訂購的用戶數量(基於他們的電子郵件地址eo_email)。架構Mysql計算重複行的百分比

這裏下的例子是代表我的餐館

CREATE TABLE IF NOT EXISTS `lf_restaurants` (
    `r_id` int(8) NOT NULL AUTO_INCREMENT, 
    `r_name` varchar(128) DEFAULT NOT NULL, 
    PRIMARY KEY (`r_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ; 

INSERT INTO `lf_restaurants` (`eo_id`, `eo_ref_id`) VALUES 
('1', 'Restaurant X'), 
('2', 'Cafe Y'); 

的桌子,這是我的訂單表

CREATE TABLE IF NOT EXISTS `ecom_orders` (
    `eo_id` mediumint(9) NOT NULL AUTO_INCREMENT, 
    `eo_ref_id` varchar(12) DEFAULT NOT NULL, 
    `eo_email` varchar(255) DEFAULT NOT NULL, 
    `eo_order_parent` int(11) NOT NULL, 
    PRIMARY KEY (`eo_id`), 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ; 

INSERT INTO `ecom_orders` (`eo_id`, `eo_ref_id`, `eo_email`, `eo_order_parent`) VALUES 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '1'), 
('', '', '[email protected]', '2'), 
('', '', '[email protected]', '2'), 
('', '', '[email protected]', '2'), 
('', '', '[email protected]', '2'); 

所以餐廳X(R_ID 1)有10個訂單。用戶[email protected][email protected]多次從該餐廳訂購,[email protected][email protected][email protected]只訂購了一次,因此需要返回40%

咖啡廳Y(r_id 2)有4個訂單。用戶[email protected]已經訂購了兩次,用戶[email protected][email protected]只訂購了一次,所以需要返回33%

我不確定發佈我已經得到的當我繼續運行'Subquery有超過1個結果'時,或者如果我用自己的虛擬查詢將該子查詢打包爲一個計數,它不會讓我使用主查詢所需的字段,例如r_id。但這裏有雲:

SELECT r_name, 
    (SELECT COUNT(*) AS cnt_users 
     FROM (
      SELECT * 
      FROM ecom_orders 
      WHERE eo_order_parent = r_id 
      GROUP BY eo_email 
     ) AS cnt_dummy 
    ) AS num_orders, 
    (SELECT COUNT(*) AS cnt 
     FROM ecom_orders 
     WHERE eo_order_parent = r_id 
     GROUP BY eo_order_parent, eo_email 

    ) AS num_rep_orders 
    FROM lf_restaurants 
    ORDER BY num_orders DESC 

的NUM_ORDERS子查詢是說它不承認R_ID,因爲我猜測這是由於num_rep_orders子查詢回來爲多行,一切事都執行

的順序,但我真的希望這回來只有一個值,我可以做,如果我做它像num_orders子查詢,但然後會遇到r_id不存在的問題。

所以我的問題是:我如何獲得這些價值,我需要,而不會在子查詢已超過1行,R_ID不存在?

然後從這兩個值我可以計算出百分比,所有應該是肉汁:)任何幫助非常感謝!

回答

2

所以餐廳X(r_id 1)有10個訂單。用戶[email protected][email protected]多次從該餐廳訂購 ,並且[email protected][email protected][email protected]只訂購了一次,所以它需要返回40%

咖啡廳Y(r_id 2)有4個訂單。用戶[email protected]已下令兩次,用戶 [email protected][email protected]只訂購一次,所以它需要返回 33%

好。那麼讓我們開始獲取重複客戶的數量。

SELECT eo_order_parent, eo_email, COUNT(eo_email) AS orders FROM ecom_orders 
    GROUP BY eo_order_parent, eo_email 
    HAVING orders > 1; 

而且不同的客戶

SELECT eo_order_parent, COUNT(eo_email) FROM ecom_orders 
    GROUP BY eo_order_parent; 

但是,我們可以在一個去做到這一點的總數:

SELECT eo_order_parent, 
    SUM(CASE WHEN orders > 1 THEN 1 ELSE 0 END) AS repeats, 
    SUM(1) AS total FROM 
    (
     SELECT eo_order_parent, eo_email, COUNT(*) AS orders FROM ecom_orders 
      GROUP BY eo_order_parent, eo_email 
    ) AS eo_group_1 
GROUP BY eo_order_parent; 

這給:

+-----------------+---------+-------+ 
| eo_order_parent | repeats | total | 
+-----------------+---------+-------+ 
|    1 |  2 |  5 | 
|    2 |  1 |  3 | 
+-----------------+---------+-------+ 
2 rows in set (0.00 sec) 

然後2/5是你的40%,1/3是33%。

+0

哥們兒!非常好的回答,非常優雅的解決方案:)非常感謝! – Horse

1

下面的查詢計算回頭客的數量和客戶的每餐廳

SELECT 
    u.r_id, 
    u.r_name, 
    SUM(u.no_orders > 1) AS repeats, 
    SUM(u.no_orders) AS orders, 
    COUNT(u.eo_email) AS customers 
FROM (
    SELECT 
     r.*, 
     o.eo_email, 
     COUNT(o.eo_id) AS no_orders 
    FROM lf_restaurants r 
    LEFT JOIN ecom_orders o ON o.eo_order_parent = r.r_id 
    GROUP BY o.eo_email 
) u 
GROUP BY 
    r.r_id; 

子查詢首先計算每個客戶/餐廳對訂單數量的總數。外部查詢根據此計算客戶數量,重複客戶數量以及每個餐廳的總客戶數量。您也可以計算百分比(但這不一定在查詢中完成)。

+0

感謝您的答案,但'字段列表'中的未知列'u.no_order' – Horse

+0

@Horse:哎呦,錯字 – Martijn