2 列のサブ行を重複として含むすべての行をリストする SQL クエリは何ですか?
-
02-07-2019 - |
質問
冗長なデータを含むテーブルがあり、重複したサブ行を持つすべての行を識別しようとしています(適切な言葉がありません)。下位行とは、検討することを意味します COL1
そして COL2
のみ。
それで、次のようなものがあるとしましょう:
COL1 COL2 COL3
---------------------
aa 111 blah_x
aa 111 blah_j
aa 112 blah_m
ab 111 blah_s
bb 112 blah_d
bb 112 blah_d
cc 112 blah_w
cc 113 blah_p
これを返す SQL クエリが必要です。
COL1 COL2 COL3
---------------------
aa 111 blah_x
aa 111 blah_j
bb 112 blah_d
bb 112 blah_d
解決
これは役に立ちますか?
select t.* from table t
left join ( select col1, col2, count(*) as count from table group by col1, col2 ) c on t.col1=c.col1 and t.col2=c.col2
where c.count > 1
他のヒント
リストされたデータでは、クエリは実行できません。行 5 と行 6 のデータは、それ自体では区別されません。
テーブルの名前が「quux」であると仮定して、次のような内容から始めるとします。
SELECT a.COL1, a.COL2, a.COL3
FROM quux a, quux b
WHERE a.COL1 = b.COL1 AND a.COL2 = b.COL2 AND a.COL3 <> b.COL3
ORDER BY a.COL1, a.COL2
最終的には次のような答えになります。
COL1 COL2 COL3
---------------------
aa 111 blah_x
aa 111 blah_j
これは、行 5 と行 6 の COL3 の値が同じであるためです。行 5 と 6 の両方を返すクエリは、このデータセット内のすべての行の重複も返します。
一方、主キー (ID) がある場合は、代わりに次のクエリを使用できます。
SELECT a.COL1, a.COL2, a.COL3
FROM quux a, quux b
WHERE a.COL1 = b.COL1 AND a.COL2 = b.COL2 AND a.ID <> b.ID
ORDER BY a.COL1, a.COL2
[WHERE句を簡略化するために編集しました]
そして、望む結果が得られます。
COL1 COL2 COL3
---------------------
aa 111 blah_x
aa 111 blah_j
bb 112 blah_d
bb 112 blah_d
これは SQL Server 2000 でテストしましたが、最新の SQL データベースでも同じ結果が表示されるはずです。
次のように自分自身に参加してください。
SELECT a.col3, b.col3, a.col1, a.col2
FROM tablename a, tablename b
WHERE a.col1 = b.col1 AND a.col2 = b.col2 AND a.col3 != b.col3
postgresql を使用している場合は、次のように oid を使用して、返される結果の重複を減らすことができます。
SELECT a.col3, b.col3, a.col1, a.col2
FROM tablename a, tablename b
WHERE a.col1 = b.col1 AND a.col2 = b.col2 AND a.col3 != b.col3
AND a.oid < b.oid
これをテストするのに便利なデータベースはありませんが、うまくいくはずだと思います...
select
*
from
theTable
where
col1 in
(
select
col1
from
theTable
group by
col1||col2
having
count(col1||col2) > 1
)
私の素朴な試みは次のようになります
select a.*, b.* from table a, table b where a.col1 = b.col1 and a.col2 = b.col2 and a.col3 != b.col3;
ただし、これではすべての行が 2 回返されます。一度だけ返品するように制限する方法がわかりません。主キーがある場合は、「and a.pkey < b.pkey」を追加できるかもしれません。
先ほども言いましたが、これはエレガントではないので、おそらくもっと良い方法があるでしょう。
次のようなものが機能するはずです。
SELECT a.COL1, a.COL2, a.COL3
FROM YourTable a
JOIN YourTable b ON b.COL1 = a.COL1 AND b.COL2 = a.COL2 AND b.COL3 <> a.COL3
一般に、JOIN 句には、「重複」の一部であると考えられるすべての列 (この場合は COL1 と COL2) を含める必要があり、行の結合を排除するために少なくとも 1 つの列 (または必要なだけ多くの列) を含める必要があります。それ自体 (この場合は COL3) に。
これは自己結合とよく似ていますが、重複がない点が異なります。
select COL1,COL2,COL3
from theTable a
where exists (select 'x'
from theTable b
where a.col1=b.col1
and a.col2=b.col2
and a.col3<>b.col3)
order by col1,col2,col3
重複を見つける方法は次のとおりです。データを使用して Oracle 10g でテストされました。
tstから[col1] in(col1、col2からcol1を選択します。
COL1、COL2、COL3を選択
テーブルから
COL1、COL2、COL3ごとにグループ化
count(*)>1 を持つ
結合は無視して、分析関数を使用します。
select col1, col2, col3
from
(
select col1, col2, col3, count(*) over (partition by col1, col2) rows_per_col1_col2
from table
)
where rows_per_col1_col2 > 1