2016-11-03 3 views
1

ある列の値または別の列の値のいずれかがある結果セットから行を削除する最良の方法を理解しようとしています。結果セットの複製。SQL理論:ある列の重複を除外し、他の列で最も低い値を取り出す

次のようにクエリの結果は想像:

a_value | b_value 
----------------- 
    1 | 1 
    2 | 1 
    2 | 2 
    3 | 1 
    4 | 3 
    5 | 2 
    6 | 4 
    6 | 5 

私が何をしたいです:

  • がa_value
  • に重複する値を持つすべての行が1行のみを選択してください排除します指定されたb_valueについて

だから、私はこのように終わるようにフィルタリングされた結果を望んでいますa_value重複をなくしTER:

a_value | b_value 
----------------- 
    1 | 1 
    3 | 1 
    4 | 3 
    5 | 2 

そして、このように一つだけb_value摘み後:

a_value | b_value 
----------------- 
    1 | 1 
    4 | 3 
    5 | 2 

を私はSQLを介した効率的な方法でこのタスクを実行する方法についての提案をいただければと思います。私はa_value 列に存在するすべての重複を回避し、入力されたテーブルからすべての残りの行を取得し、それらをT2と
を記憶していインナークエリで

+0

ないなど、一時テーブルなどの任意の制限は、?また、SQL Server、mysql、oracle、または? – Nikki9696

+0

データにID列がありますか? yesの場合 - mysqlを使用している場合は、左結合を使用できます。少なくとも最初のフィルタリングされた結果の場合 – Seb

+0

私の場合、Oracleです。 2つのテーブルから来る大量のデータセットの方が効率的であれば、テンポラリテーブルは問題ありません。 – Chill

答えて

1
with 
    q_res (a_value, b_value) as (
     select 1, 1 from dual union all 
     select 2, 1 from dual union all 
     select 2, 2 from dual union all 
     select 3, 1 from dual union all 
     select 4, 3 from dual union all 
     select 5, 2 from dual union all 
     select 6, 4 from dual union all 
     select 6, 5 from dual 
    ) 
-- end test data; solution begins below 
select min(a_value) as a_value, b_value 
from  ( 
      select a_value, min(b_value) as b_value 
      from  q_res 
      group by a_value 
      having count(*) = 1 
     ) 
group by b_value 
order by a_value -- ORDER BY is optional 
; 

A_VALUE B_VALUE 
------- ------- 
     1  1 
     4  3 
     5  2 
1

1)。 t2とt1を結合することによって、 の#1の要求に従うと、完全なデータはなくなります。フィルタリングされたデータが得られると

SELECT t1.* 
    FROM Table t1, 
     (
     SELECT a_value  
      FROM Table 
     GROUP BY a_value 
     HAVING COUNT(*) = 1 
     ) t2 
    WHERE t1.a_value = t2.a_value; 

2)、Iは、ステップ1で得られた濾過データセットの各行にランクを割り当てていると私は、ランク= 1の行のみを選択しています。

SELECT X.a_value, 
     X.b_value 
    FROM 
    (
     SELECT t1.*, 
       ROW_NUMBER() OVER (PARTITION BY t1.b_value ORDER BY t1.a_value,t1.b_value) AS rn 
      FROM Table t1, 
      (
       SELECT a_value  
       FROM Table 
       GROUP BY a_value 
       HAVING COUNT(*) = 1 
      ) t2 
     WHERE t1.a_value = t2.a_value 
     ) X 
WHERE X.rn = 1; 
+0

これは本当にこれを実行する最善の方法ですか?グループ化またはウィンドウ関数を使用してフィルタリングを適用する他の選択肢に結果をラップするだけですか? – Chill

+0

上記はあなたの質問に答えますか? – Teja

+0

両方のテーブルの間に1-1結合があると想定していますが、そうではありませんが、その方法の基本については答えています。私は選択クエリの2つの他のレイヤー(効果的に)で選択クエリをラッピングするよりも良い方法があることを期待していました。 – Chill

関連する問題