2010-02-26 14 views
2

잘 설명해 드리겠습니다. 나는 선 주문 테이블이 (각 행의 순서는 항목과 가격의 양으로 구성되어, 거기에 다른 분야는하지만 나는 그를 떠났다.)주문 통계를 주문순으로 그룹화합니다.

테이블 'ORDERITEMS는'

orderid | quantity | price 
1  | 1  | 1.5000 
1  | 2  | 3.22 
2  | 1  | 9.99 
3  | 4  | 0.44 
3  | 2  | 15.99 

것은 그래서 얻을 수 주문 전체 실행

그러나 $ 1 미만의 모든 주문에 대해 계산하고 싶습니다.

내 최종 결과는 $ 1, $ 1 - $ 3, 3-5, 5-10, 10-15, ... 등의 범위를 정의 할 수 있습니다. ;

내 데이터

때문에 (희망)과 같이합니다 : 나는 우리의 전자 상거래 사이트에서 고객 주문의 pieChart에 고장을 제시 할 수

tunder1 | t1to3 | t3to5 | t5to10 | etc 
10  | 500 | 123 | 5633 | 

그래야. 이제이 작업을 수행하기 위해 개별 SQL 쿼리를 실행할 수 있지만 가장 효율적인 '단일 SQL 쿼리'가 무엇인지 알고 싶습니다. MS SQL Server를 사용하고 있습니다.

현재 나는 총 $ 1 항에 따라 얻을 수 있도록 같은 단일 쿼리를 실행할 수 있습니다

SELECT  COUNT(total) AS tunder1 
FROM   (SELECT  SUM(Quantity * price) AS total 
         FROM   OrderItems 
         GROUP BY OrderID) AS a 
WHERE  (total < 1) 

어떻게이 최적화 할 수 있습니까? 미리 감사드립니다!

답변

2
select 
    count(case when total < 1 then 1 end) tunder1, 
    count(case when total >= 1 and total < 3 then 1 end) t1to3, 
    count(case when total >= 3 and total < 5 then 1 end) t3to5, 
    ... 
from 
(
    select sum(quantity * price) as total 
    from orderitems group by orderid 
); 
+1

파생 테이블의 이름을 지정해야합니다. 그렇지 않으면 오류가 발생하고');'을') dt'로 바꿉니다. 또한, 이것은 또한 경고 : 경고 : Null 값은 집계 또는 다른 SET 연산에 의해 제거됩니다.'ELSE 0으로 답할 때처럼 SUM()을 사용하면이 문제가 해결됩니다. –

+0

흠, 나는 오라클을 훨씬 좋아한다 ;-). –

1

그룹화 된 값을 필터링하려면 HAVING을 사용해야합니다.

1

이 시도 :

DECLARE @YourTable table (OrderID int, Quantity int, Price decimal) 
INSERT INTO @YourTable VALUES (1,1,1.5000) 
INSERT INTO @YourTable VALUES (1,2,3.22) 
INSERT INTO @YourTable VALUES (2,1,9.99) 
INSERT INTO @YourTable VALUES (3,4,0.44) 
INSERT INTO @YourTable VALUES (3,2,15.99) 

SELECT 
    SUM(CASE WHEN TotalCost<1 THEN 1 ELSE 0 END) AS tunder1 
     ,SUM(CASE WHEN TotalCost>=1 AND TotalCost<3 THEN 1 ELSE 0 END) AS t1to3 
     ,SUM(CASE WHEN TotalCost>=3 AND TotalCost<5 THEN 1 ELSE 0 END) AS t3to5 
     ,SUM(CASE WHEN TotalCost>=5 THEN 1 ELSE 0 END) AS t5andup 
    FROM (SELECT 
       SUM(quantity * price) AS TotalCost 
       FROM @YourTable 
       GROUP BY OrderID 
     ) dt 

출력 :

tunder1  t1to3  t3to5  t5andup 
----------- ----------- ----------- ----------- 
0   0   0   3 

(1 row(s) affected) 
0
WITH orders (orderid, quantity, price) AS 
     (
     SELECT 1, 1, 1.5 
     UNION ALL 
     SELECT 1, 2, 3.22 
     UNION ALL 
     SELECT 2, 1, 9.99 
     UNION ALL 
     SELECT 3, 4, 0.44 
     UNION ALL 
     SELECT 4, 2, 15.99 
     ), 
     ranges (bound) AS 
     (
     SELECT 1 
     UNION ALL 
     SELECT 3 
     UNION ALL 
     SELECT 5 
     UNION ALL 
     SELECT 10 
     UNION ALL 
     SELECT 15 
     ), 
     rr AS 
     (
     SELECT bound, ROW_NUMBER() OVER (ORDER BY bound) AS rn 
     FROM ranges 
     ), 
     r AS 
     (
     SELECT COALESCE(rf.rn, 0) AS rn, COALESCE(rf.bound, 0) AS f, 
       rt.bound AS t 
     FROM rr rf 
     FULL JOIN 
       rr rt 
     ON  rt.rn = rf.rn + 1 
     ) 
SELECT rn, f, t, COUNT(*) AS cnt 
FROM r 
JOIN (
     SELECT SUM(quantity * price) AS total 
     FROM orders 
     GROUP BY 
       orderid 
     ) o 
ON  total >= f 
     AND total < COALESCE(t, 10000000) 
GROUP BY 
     rn, t, f 

출력 :

rn  f  t  cnt 
1  1  3  1 
3  5  10  2 
5  15  NULL 1 

, 즉 $1에서 $31 순서입니다, $5 ~ $10, 1보다 2 주문은 $15 이상 주문하십시오.

+0

woah ... 그게 무슨 뜻인지 설명해 주시겠습니까? 나는 지금 ar의 대답을보고있다. 이 기능이 어떻게 작동하는지 궁금하십니까? – Jakub

+0

@ Jakub : 먼저 '범위'에 제공된 범위를 기준으로 범위의 레코드 세트를 만듭니다. 둘째, 모든 주문의 합계를 계산합니다. 셋째, 범위와 합계를 조인하고 각 범위 내의 수를 계산합니다. – Quassnoi

관련 문제