2013-02-21 22 views
4

我還在學習Oracle SQL,希望得到您的指導。通過SQL查詢來識別「最佳執行者」[?]

比方說,我們有MONTHLY_SALES_TOTALS表有3個字段:name,region,amount。我們需要確定每個地區的最佳銷售人員。最佳意味着它們的數量等於該地區的最大數量。

CREATE TABLE montly_sales_totals 
(
name varchar(20), 
amount numeric(9), 
region varchar(30) 
); 

INSERT ALL 
INTO montly_sales_totals (name, amount, region) VALUES ('Peter', 55555, 'east') 
INTO montly_sales_totals (name, amount, region) VALUES ('Susan', 55555, 'east') 
INTO montly_sales_totals (name, amount, region) VALUES ('Mark', 1000000, 'south') 
INTO montly_sales_totals (name, amount, region) VALUES ('Glenn', 50000, 'east') 
INTO montly_sales_totals (name, amount, region) VALUES ('Paul', 500000, 'south') 
SELECT * from dual; 

可能的解決辦法:

SELECT m1.name, m1.region, m1.amount 
FROM montly_sales_totals m1 
JOIN 
(SELECT MAX(amount) max_amount, region FROM montly_sales_totals GROUP BY region) m2 
ON (m1.region = m2.region) 
WHERE m1.amount = m2.max_amount 
ORDER by 2,1; 

SQL小提琴http://sqlfiddle.com/#!4/6a2d8/6

現在我的問題:

  1. 效率如何這樣的查詢?
  2. 如何簡化和/或改進?
  3. 我無法使用頂部由於「最大」行的數量因地區而異。它可以用來代替另一個直接功能嗎?

回答

5

我會用RANK():

SELECT * 
FROM (
    SELECT name, amount, region, 
     RANK() OVER (PARTITION BY region ORDER BY amount DESC) rnk 
    FROM montly_sales_totals 
) t 
WHERE t.rnk = 1 

這裏的SQL Fiddle

1

修改後的版本有很多種方式可以去這個問題。這是另一種:

 select S.region, S.name, V.regionmax 
     from sales as S 
     inner join 
     (
     select region, max(amount) as regionmax 
     from sales group by region 
     ) as V 
     on S.region = V.region and S.amount = regionmax 

至於效率,主要因素是使用正確的索引。內聯視圖可以很好地執行。

1

我喜歡CTE語法,但使用該網站所花的時間是一樣的2ms的,所以我不能擊敗你的:)

with Maximums as (
    SELECT region, 
    MAX(amount) max_amount 
    FROM montly_sales_totals GROUP BY region 
) 
SELECT m1.name, m1.region, m1.amount 
FROM montly_sales_totals m1, Maximums 
WHERE (m1.amount = Maximums.max_amount) 
    and (m1.region = Maximums.region) 
ORDER by 2,1; 
+0

但是在where子句中,您也需要包含該區域。 – Tim 2013-02-22 12:11:14

+0

謝謝蒂姆,現在編輯。 – 2013-02-22 13:15:11

0

您可以通過使用功能也做到這一點...

select * from (select m1.*, row_number() over (partition by m1.region order by m1.amount desc,m1.name desc) max_sal from montly_sales_totals m1) where max_sal =1 ; 

這個查詢可以做一個額外的事情,如果兩個員工薩爾是相同的!

+0

每個地區可以擁有**多個**最佳表演者。 – 2013-02-22 17:03:33

+0

哦...你的意思是你需要候​​選人的名字....誰擁有等於最高金額的權利!? – 2013-02-22 17:55:31

+0

是的。這是我原來的帖子中的拼寫。 – 2013-02-22 18:16:22