2011-11-30 2 views
0

기본적으로 특정 열의 값을 요약하려고합니다. 지금 내 쿼리는 다음과 같습니다사례를 사용할 때 SUM 열 지정

SELECT 
DATE(paid_at) AS day, 
(SELECT sum(shipping_costs) from orders where shipping_method = 'mondial_relais' and DATE(paid_at) = day) as mr_revenue_real 
FROM orders 
WHERE MONTH(paid_at) = 10 
AND YEAR(paid_at) = 2011 
GROUP BY day; 

나는 성능을 향상시키기 위해 mr_revenue_real의 하위 쿼리를 대체 할하지만 할 방법을 모르겠어요. 이것은 내가 염두에 두었던 것입니다 : sum(case when hipping_method = 'mondial_relais' and DATE(paid_at) = day then 1 end) as mr_revenue_real하지만 어디에서든지 shipping_costs의 합계가 필요하지 않기 때문에이 방법이 작동하지 않습니다.

아이디어가 있으십니까?

답변

2
sum(case when shipping_method='mondial_relais' then shipping_costs else 0 end) 

전체 쿼리과 같이

SELECT 
DATE(paid_at) AS day, 
sum(case when shipping_method='mondial_relais' then shipping_costs else 0 end) 
FROM orders 
WHERE MONTH(paid_at) = 10 AND YEAR(paid_at) = 2011 
GROUP BY day; 
2

:

SELECT 
     DATE(paid_at) AS day, 
     sum(case when shipping_method = 'mondial_relais' 
      then shipping_costs end) as mr_revenue_real 
    FROM orders 
    WHERE MONTH(paid_at) = 10 
    AND YEAR(paid_at) = 2011 
    GROUP BY day; 

(. 이미 DATE(paid_at) AS day에 의해 그룹화되어 있기 때문에 당신은 DATE(paid_at) = day을 지정할 필요가 없습니다)

1

먼저 다음을 교체하십시오.

와 617,451,515,
WHERE MONTH(paid_at) = 10 AND YEAR(paid_at) = 2011 

:

WHERE paid_at >= '2011-10-01' 
    AND paid_at < '2011-10-01' + INTERVAL 1 MONTH 

그래서 당신은 paid_at에 인덱스가 있다면, 그것은 사용되며 쿼리는 전체 테이블을 스캔 할 필요가 없으며, 모든 행에 대해 YEAR()MONTH() 함수를 호출하지 않습니다 .


둘째, 당신은 SELECT 목록에서 하위 쿼리가 필요하지 않습니다. 이 같은 것을 사용할 수 있습니다

SELECT 
    DATE(paid_at) AS day, 
    SUM(CASE WHEN shipping_method = 'mondial_relais' 
        THEN shipping_costs 
       ELSE 0 
     END 
     ) AS mr_revenue_real 
FROM orders 
WHERE paid_at >= '2011-10-01' 
    AND paid_at < '2011-10-01' + INTERVAL 1 MONTH 
GROUP BY DATE(paid_at) 

또한 아마 더 빨리 (shipping_method, paid_at) 인덱스가있는 것이 쿼리를 사용할 수 있습니다. 그러나 주문이없는 요일은 shipping_method = 'mondial_relais'으로 표시되지 않습니다.

SELECT 
    DATE(paid_at) AS day, 
    SUM(shipping_costs) AS mr_revenue_real 
FROM orders 
WHERE shipping_method = 'mondial_relais' 
    AND paid_at >= '2011-10-01' 
    AND paid_at < '2011-10-01' + INTERVAL 1 MONTH 
GROUP BY DATE(paid_at) 
+0

왜 이런 이유가 더 좋을까요? – networkprofile