2016-08-08 3 views
2

私はさまざまなカテゴリのデータベースを持っています。各カテゴリについては3つの数量があり、カテゴリあたりの数量ごとに25番目に大きな値を含む行を抽出したい(関係は無視しても問題ありません)。異なる行からランク付けされた値を抽出する - SQL

たとえば、ある行がいくつかの国の町や都市であったデータベースがあるとします。カテゴリは国であり、量は人口、土地面積、緯度である可能性があります。この例では、私は25日、最大彼らの第25回最大の人口、25日最大の国土面積と一緒に、リスト内の国のそれぞれのようになりたいと思う最終結果を

TownName Country Population LandArea Latitude 
Paris  France  500,715  47.9  45.76 
Manchester USA  110,229  90.6  42.99 
Calais  France  72,589  33.5  50.95 
Leicester England 337,653  73.3  52.63 
Dunkirk  France  90,995  43.9  51.04 
...   ...  ...   ...   ... 

:データは、その後のようになります。緯度。これはもはや特定の町や都市に似ていなくても、各国に関する情報を提供します。私は次の操作を実行するためにあった、これを実行する1つの方法を考え出した

Country Population LandArea Latitude 
France  144,548  83.95  50.21 
Poland  141,080  88.3  54.17 
Australia 68,572  146   -21.35 
...  ...   ...   ... 

  1. は人口、LandAreaと緯度の1をランク付けするROW_NUMBER機能を使用してこれは次のようになります降順で、国ごとに分割されています。

  2. この3回(量ごとに1回)、および3つのデータベースを一緒に繰り返します。 ONステートメントでは、ランク列の値と同じように、Country列の値が等しいことを確認します。

  3. は、それがコードへのまともなサイズのチャンクの3つのほとんど正確なコピーを作成関わるので、私はこの方法を好きではないランク25

で、それぞれの国の行を引き出すためにWHEREステートメントを使用します私は一緒に参加した3つの別々のデータベースを取得します(これは単純な例であるため、結合ステートメントの各コードブロックはまともなサイズでしたが、このような段階になるためには他のものをやらなければなりませんでした)。

JOINステートメントで大量のコードを繰り返し実行する方法がないのかどうか疑問に思っていました。これによってコードが大きくて醜いものになりました。また、これは何度も時間がかかるかもしれないので、より効率的な方法が素晴らしいだろう。あなたは3-参加アプローチを排除するための方法を見つけることができない場合、あなたはそれぞれ個別のタプルにGroupIDを割り当てることにより、結合条件を簡素化することができますおそらく、あなたの時間

+0

使用同じクエリで異なる「ORDER BY」を持つ3つの別々の分析式?おそらく、 –

+0

。私は前にそのようなものを試してみましたが、それはうまくいきませんでしたが、それは有望であると思いますので、私は今それをもう一度行っています(私はかなりSQLに新しいので、かなり明白な何かを逃した可能性があります) – hodgenovice

+0

@ PM77-1私が試み: 国を選択し、 (TOP 25人口ORDER BY PopulationRankを選択)、 (AreaRank BY TOP 25 LandArea順を選択)、 (LatRank BY TOP 25緯度順を選択) FROM [ランクを有するデータのコードをすでに完了しました] GROUP BY国 しかし、それは私がそれをカットすることができたとしても、それは私に正しい種類のものを与えているとは思わない(私はWHERE句を試しましたが、それは良くありませんでした。たぶんあなたは別の行に沿って何かを考えていたと私は誤解した? 私は明日これに戻るつもりです。コメントありがとう。 – hodgenovice

答えて

1

ため

ありがとう:

;WITH 
    MasterCTE AS 
    (
     SELECT  *, 
        DENSE_RANK() OVER (ORDER BY Country) AS GroupID -- Don't use ROW_NUMBER here. RANK or DEMSE_RANK only 
     FROM  MyTable 
    ), 
    cte1 AS 
    (
     SELECT  GroupID, [Population], 
        ROW_NUMBER() OVER (PARTITION BY GroupID ORDER BY [Population] DESC) AS PopulationRank 
     FROM  MasterCTE 
    ), 
    cte2 AS 
    (
     SELECT  GroupID, LandArea, 
        ROW_NUMBER() OVER (PARTITION BY GroupID ORDER BY LandArea DESC) AS LandAreaRank 
     FROM  MasterCTE 
    ), 
    cte3 AS 
    (
     SELECT  GroupID, Latitude, 
        ROW_NUMBER() OVER (PARTITION BY GroupID ORDER BY Latitude DESC) AS LatitudeRank 
     FROM  MasterCTE 
    ) 


SELECT DISTINCT -- Remember to include DISTINCT 
      MasterCTE.Country, 
      cte1.Population, cte2.LandArea, cte3.Latitude 
FROM  MasterCTE 
INNER JOIN cte1  ON MasterCTE.GroupID = cte1.GroupID AND cte1.PopulationRank = 25 
INNER JOIN cte2  ON MasterCTE.GroupID = cte2.GroupID AND cte2.LandAreaRank = 25 
INNER JOIN cte3  ON MasterCTE.GroupID = cte3.GroupID AND cte3.LatitudeRank = 25 
関連する問題