0

私は Oracle 11g Release 1 を使用しています。この質問についてフォローアップします。

この行のセットを持つ:

Name     Contact_No

A        123
A        124
B        125
C        126
C        127

分析関数を使用してこれを返したいと思います:

Name     Contact_No
B        125

私はこれを行うことができました

select name, Contact_No
from   tbl_name
where  name in ( SELECT name
                 FROM   tbl_name
                 GROUP  BY name
                 HAVING COUNT(name) = 1
                )

またはこれ

SELECT name, max(Contact_No)
FROM   tbl_name
GROUP  BY name
HAVING COUNT(name) = 1

しかし、コードを読む人を混乱させる可能性のあるサブクエリを回避したり、テーブルをそれ自体と結合したり、最小値/最大値を使用したりすることを回避できるソリューションが必要です! これは分析関数で可能だと思いますが、方法がわかりませんか?

4

1 に答える 1

2

そうです、分析関数を使用する必要があります。行全体を返したい場合。現在のクエリから判断すると、分析的COUNT()です。

select *
  from ( select a.*, count(*) over ( partition by name ) as ct
           from tbl_name )
 where ct = 1

説明すると、partition by は、実際には GROUP BY と同じですが、実行しないことを除きます。これは、名前ごとのレコード数をカウントし、その名前のレコード数に関係なく、インラインで返します。その後、この生成された列を制限できます。

これはサブクエリを使用しますが、この方法に本質的な問題はありません。テーブル/インデックスを 1 回だけスキャンします。2回スキャンする現在の例とは異なります。

通常はここにインデックスを作成することをお勧めしますが、NAME特定の状況によって異なります。テーブル全体をスキャンする必要がある場合があります。その場合、インデックスは役に立ちません。

さらに、これらの 2 つの列しかない場合、分析クエリには意味がありません。2 番目のオプションを使用して、同じ結果を得ることができます。

SELECT name, max(Contact_No)
  FROM tbl_name
 GROUP BY name
HAVING COUNT(name) = 1

分析クエリは、GROUP BY に含めることができない追加の列を返す必要がある場合に役立ちます。

于 2013-04-05T12:03:06.487 に答える