2017-02-21 12 views
0

行に存在する重複値を削除する必要があります。 のようなクエリの行の重複値(2列の組み合わせ)を削除します

C1 | C2 | C3 | C4 | C5 | C6 
---------------------------- 
1 | 2 | 1 | 2 | 1 | 3 
1 | 2 | 1 | 3 | 1 | 4 
1 |NULL| 1 |NULL| 1 |NULL 

OUTPUTは次のようになります。

C1 | C2 | C3 | C4 | C5 | C6 
---------------------------- 
1 | 2 | 1 | 3 |NULL|NULL 
1 | 2 | 1 | 3 | 1 | 4 
1 |NULL|NULL|NULL|NULL|NULL 

あなたは2列の組合せが行で一意である必要があります見ることができるように。

行1における


1/2 組み合わせがそうその除去を複製し1/3 C5/C6であるが行2のC3/C4

に移動される。
なしあり
すべて3つの組み合わせは1/NULLはすべての組み合わせで存在しているように同じである:1/2、1/3、1/4の組み合わせの行3における結果にそれほど変化

重複しませんしたがって、c3からc6はヌルに設定されます。

事前

+2

あなたの質問はあまり正確ではありません。正確に何が必要ですか?あなたの例は多くの点で解釈でき、あなたの記述の種類はそれ自身と矛盾します。 「行内に重複する値を取り除く」は、「2列の組み合わせが一意でなければならない」と同じではありません。また、どの組み合わせがユニークであるべきですか? – m00hk00h

+0

質問を更新しました! – Biswabid

+0

すべての列が同じテーブルから来ていますか?クエリのSQLを表示します。 –

答えて

0

のおかげではたぶんもっと賢い方法がある...しかし、あなたは異なった、ペアにそれらを変換することができ(この場合は労働組合があることない)、その後、戻って旋回します。下のコードスニペットをアンコメント - 、デバッグラインだけでこれらのコードまでのスクリプトをコピーします。データはテストのために含まれていますが、

先端を理解するためにいくつかの時間がかかることがあります -

with pairs as (
    select id, c1 as x, c2 as y from mytable 
    union 
    select id, c3, c4 from mytable 
    union 
    select id, c5, c6 from mytable 
) 
select id, 
     max(decode(rn,1,x)) c1, 
     max(decode(rn,1,y)) c2, 
     max(decode(rn,2,x)) c3, 
     max(decode(rn,2,y)) c4, 
     max(decode(rn,3,x)) c5, 
     max(decode(rn,3,y)) c6 
from (
    select id, x, y, row_number() over (partition by id) rn 
    from pairs 
) as foo 
group by id 
0

この1つは動作しますこの断片をSQLプロンプトに貼り付け、中間結果をテストします。

原則は行を「記憶」する行識別子を取得することです。次に3列ではなく、6列から3列の列を垂直にピボットする。次に、DISTINCTを使用して重複排除を行います。重複排除された中間行の行識別子内の索引を取得します。そのインデックスを使用して再び水平にピボットします。そのよう

WITH 
input(c1,c2,c3,c4,c5,c6) AS (
      SELECT 1,  2,1,  2,1,  3 
UNION ALL SELECT 1,  2,1,  3,1,  4 
UNION ALL SELECT 1,NULL::INT,1,NULL::INT,1,NULL::INT 
) 
, 
-- need rowid 
input_with_rowid AS (
SELECT ROW_NUMBER() OVER() AS rowid, * FROM input 
) 
, 
-- three groupy of 2 columns, so pivot using 3 indexes 
idx3(idx) AS (SELECT 1 UNION SELECT 2 UNION SELECT 3) 
, 
-- pivot vertically, two columns at a time and de-dupe 
pivot_pair AS (
SELECT DISTINCT 
    rowid 
, CASE idx 
    WHEN 1 THEN c1 
    WHEN 2 THEN c3 
    WHEN 3 THEN c5 
    END AS c1 
, 
    CASE idx 
    WHEN 1 THEN c2 
    WHEN 2 THEN c4 
    WHEN 3 THEN c6 
    END AS c2 
FROM input_with_rowid CROSS JOIN idx3 
) 
-- debug 
-- SELECT * FROM pivot_pair ORDER BY rowid; 
, 
-- add sequence per rowid 
pivot_pair_with_seq AS (
SELECT 
    rowid 
, ROW_NUMBER() OVER(PARTITION BY rowid) AS seq 
, c1 
, c2 
FROM pivot_pair 
) 
-- debug 
-- SELECT * FROM pivot_pair_with_seq; 

SELECT 
    rowid 
, MAX(CASE seq WHEN 1 THEN c1 END) AS c1 
, MAX(CASE seq WHEN 1 THEN c2 END) AS c2 
, MAX(CASE seq WHEN 2 THEN c1 END) AS c3 
, MAX(CASE seq WHEN 2 THEN c2 END) AS c4 
, MAX(CASE seq WHEN 3 THEN c1 END) AS c5 
, MAX(CASE seq WHEN 3 THEN c2 END) AS c6 
FROM pivot_pair_with_seq 
GROUP BY rowid 
ORDER BY rowid 
; 

rowid|c1|c2|c3|c4|c5|c6 
    1| 1| 2| 1| 3|- |- 
    2| 1| 2| 1| 3| 1| 4 
    3| 1|- |- |- |- |- 
0

ピボット/アンピボット演算子を持つmarcothesaneのアイデアを使用します。より多くの入力列を重複排除する必要がある場合は、保守が容易です。これにより、ソースデータ(列ペア)の順序が維持されますが、marcothesaneのソリューションでは、入力データに依存する列ペアの順序が変更される可能性があります。また、それはmarcothesaneより少し遅いです。 11R1以降でのみ動作します。

WITH 
input(c1,c2,c3,c4,c5,c6) AS (
      SELECT 1,  2,1,  2,1,  3 from dual 
UNION ALL SELECT 1,  2,1,  3,1,  4 from dual 
UNION ALL SELECT 1,NULL ,1,NULL ,1,NULL from dual 
) 
, 
-- need rowid 
input_with_rowid AS (
SELECT ROW_NUMBER() OVER (order by 1) AS row_id, input.* FROM input 
), 
unpivoted_pairs as 
(
    select row_id, tuple_idx, val1, val2, row_number() over (partition by row_id, val1, val2 order by tuple_idx) as keep_first 
    from input_with_rowid 
    UnPivot include nulls(
      (val1, val2) --measure 
       for tuple_idx in ((c1,c2) as 1, 
            (c3,c4) as 2, 
            (c5,c6) as 3) 
     ) 
) 
select row_id, 
     t1_val1 as c1, 
     t1_val2 as c2, 
     t2_val1 as c3, 
     t2_val2 as c4, 
     t3_val1 as c5, 
     t3_val2 as c6 
from (
     select row_id, 
      val1, val2, row_number() over (partition by row_id order by tuple_idx) as tuple_order 
     from unpivoted_pairs 
     where keep_first = 1 
    ) 
pivot (sum(val1) as val1, sum(val2) as val2 
     for tuple_order in ('1' as t1, '2' as t2, '3' as t3) 
     ) 
関連する問題