2 列のサブ行を重複として含むすべての行をリストする SQL クエリは何ですか?

StackOverflow https://stackoverflow.com/questions/131014

  •  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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top