2012-09-12 5 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와 같은 기본 쿼리에서 필요한 필드를 사용할 수있게됩니다. 하지만, 여기에 간다 다음 NUM_ORDERS 하위 쿼리가 I이이 num_rep_orders 하위 쿼리가 다시 여러 행이오고 일이

실행되는 순서에 의한 추측하고있다대로, 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 doesnt 존재 문제로 실행하면 할 수있는 하나의 값으로 돌아오고 싶습니다.

그래서 내 질문은 : 어떻게 1 개 이상의 행이 하위 쿼리로 실행하지 않고 내가 필요로이 값을받을 수 있나요, 그리고 r_id가 존재하지 않습니다?

그런 다음이 2 가지 값에서 나는 백분율을 알아낼 수 있으며 모두 그 육즙이어야합니다 :) 어떤 도움을 많이 주셨습니다!

답변

2

따라서 Restaurant X (r_id 1)에는 10 개의 주문이 있습니다. 사용자 [email protected][email protected]은 해당 식당에서 여러 번 주문한 이며 [email protected], [email protected][email protected]은 한 번만 주문 했으므로 to return 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 : whoops, typo – Martijn