2013-09-27 2 views
2

거래, 주문 및 쿠폰과 같은 "많은 관계"가있는 MySQL 세 개의 테이블 세트가 있습니다.Mysql은 왼쪽 조인과 카운트를 교환합니다.

Deals 
|----|--------------| 
| id | title  | 
|----|--------------| 
| 1 | Some deal | 
| 2 | Another deal | 
|----|--------------| 

Orders 
|----|---------|-----------| 
| id | deal_id | state | 
|----|---------|-----------| 
| 1 |  1 | purchased | 
| 2 |  1 | purchased | 
| 3 |  1 | expired | 
| 4 |  2 | purchased | 
|----|---------|-----------| 

Coupons 
|----|----------| 
| id | order_id | 
|----|----------| 
| 1 |  1 | 
| 2 |  1 | 
| 3 |  1 | 
| 4 |  2 | 
| 5 |  2 | 
| 6 |  4 | 
|----|----------| 

그래서 거래에는 많은 쿠폰이있는 많은 주문이 있습니다.

내가 원하는 것은 거래 테이블을 선택하고 구매 한 주문 및 쿠폰 수를 계산하는 것입니다.

은 이미 지불 한 주문에 수를 얻는 방법을 알고

SELECT orders.*, count(coupons.id) AS coupons_count FROM orders 
LEFT JOIN coupons ON orders.id=couoons.orders_id 
WHERE orders.state='purchased' 
GROUP BY orders.id 

Orders 
|----|-----------|---------------| 
| id | state | coupons_count | 
|----|-----------|---------------| 
| 1 | purchased |    3 | 
| 2 | purchased |    2 | 
| 4 | purchased |    1 | 
|----|-----------|---------------| 

내 질문은 : 어떻게 할

SELECT deals.*, count(orders.id) AS orders_purchased_count FROM deals 
LEFT JOIN orders ON deals.id=orders.deal_id AND orders.state='purchased' 
WHERE deal_id < 3 
GROUP BY deals.id 

Deals 
|----|--------------|------------------------| 
| id | title  | orders_purchased_count | 
|----|--------------|------------------------| 
| 1 | Some deal |      2 | 
| 2 | Another deal |      1 | 
|----|--------------|------------------------| 

마찬가지로, 내가 주문 쿠폰의 수를 얻을 수 있습니다 쿠폰을 합하면 orders_purchased_count 옆에 coupons_count를 추가 할 수 있습니까?

Deals 
|----|--------------|------------------------|---------------| 
| id | title  | orders_purchased_count | coupons_count | 
|----|--------------|------------------------|---------------| 
| 1 | Some deal |      2 |    5 | 
| 2 | Another deal |      1 |    1 | 
|----|--------------|------------------------|---------------| 

까다로운 것은, 내 경우에는, 내가 orders에 가입하고 내가 coupons에 가입하기 전에 orders에서 선택할 때 WHERE orders.state='purchased' 필터를 실행하기 전에 deals에서 선택할 때 WHERE deal_id < 3 필터를 실행하는 것입니다. 대용량 데이터 세트이므로 합치기 위해 내 orderscoupons을 모두 메모리에로드하고 싶지 않습니다.

어떻게해야합니까?

+0

sqlfiddle이 있습니까? – Strawberry

답변

3

이 일을 하는가에 가입? 나는 어떤 부분이 까다로울 것인지에 대한 당신의 우려를 이해할 수 없었다.

SELECT deals.*, COUNT(DISTINCT(orders.id)) AS orders_purchased_count, COUNT(coupons.id) AS coupons_count 
FROM deals 
LEFT JOIN orders 
    ON deals.id=orders.deal_id 
    AND orders.state='purchased' 
LEFT JOIN coupons 
    ON orders.id=coupons.orders_id 
WHERE deal_id < 3 
GROUP BY deals.id; 
+0

그가 힘들어 할 것 같은 "까다로운"부분은 구매 한 주문의 수를 정확하게 맞추는 것입니다. 그래서 왜 '득표'에서 '뚜렷한'것입니다. http://sqlfiddle.com/#!2/af049/26 –

+0

완벽하면 정확한 결과를 얻고 데이터 세트에서 빠르게 실행됩니다. 주문/쿠폰에 하위 쿼리를 사용해야하고 거래를 필터링하기 전에 하위 쿼리를 모두로드하지 않으려 고 걱정했습니다. 조인 만 사용하면이 문제를 피할 수 있습니다. – Devin

0

공동 관련된 하위 쿼리이 하나를 시도하고

SELECT deals.*, count(orders.id) AS orders_purchased_count 
(
SELECT count(id) FROM coupons WHERE orders_id = orders.id 

) AS coupons_count 

FROM deals 
LEFT JOIN orders ON deals.id=orders.deal_id AND orders.state='purchased' 
WHERE deal_id < 3 
GROUP BY deals.id 
관련 문제