4

私はまだOracleSQLを学習しているので、ガイダンスをお願いします。

たとえば、3つのフィールドを持つMONTHLY_SALES_TOTALSテーブルがあるとします:name、、。地域ごとに最適な営業担当者を決定する必要があります。最良とは、それらの量がその地域の最大値に等しいことを意味します。regionamount

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. 「最大」行の数は地域によって異なるため、Topを使用できませんでした。代わりに使用できたもう1つの直接的な機能ですか?
4

4 に答える 4

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フィドルの修正バージョンです

于 2013-02-21T20:18:42.887 に答える
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

効率に関しては、主な要因は適切なインデックスの使用です。インライン ビューは非常にうまく機能します。

于 2013-02-21T20:40:13.190 に答える
1

私は CTE 構文が好きですが、その Web サイトを使用すると、所要時間は同じ 2 ミリ秒なので、あなたのものに勝るものはありません :)

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;
于 2013-02-21T21:25:32.850 に答える
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 ;

両方の従業員のsalが同じである場合、このクエリは1つの追加のことを実行できます。

于 2013-02-22T14:26:02.283 に答える