web-dev-qa-db-ja.com

Oracle 11g SQLは、複数列クエリの1列で一意の値を取得します

与えられたテーブル[〜#〜] a [〜#〜]人、母国語、および他の列C3 .. ...で表されるC10

表A

[。

言語ごとに1行のすべての列を選択するクエリを作成するにはどうすればよいですか?

望ましい結果

個人の言語... 
 bob english 
 vlad russian 
 jose spanish 

それぞれの異なる言語のどの行が結果になるかは私には関係ありません。上記の結果では、各言語の最小の行番号を選択しました。

17
Ian Cohen

エリック・ペトロエリェはほぼ正しい。

SELECT * FROM TableA
WHERE ROWID IN ( SELECT MAX(ROWID) FROM TableA GROUP BY Language )

注:ROWNUM(結果セット内の行番号を提供する)ではなく、ROWID(行の一意のID)を使用する

34
Joe

これはより効率的であり、さらに値を選択するために使用する順序を制御できます。

SELECT DISTINCT
       FIRST_VALUE(person)
          OVER(PARTITION BY language
               ORDER BY person)
      ,language
FROM   tableA;

言語ごとにどの人が選ばれるかを本当に気にしない場合は、ORDER BY句を省略できます。

SELECT DISTINCT
       FIRST_VALUE(person)
          OVER(PARTITION BY language)
      ,language
FROM   tableA;
10
Jeffrey Kemp

私のOracleは少しさびていますが、これはうまくいくと思います:

SELECT * FROM TableA
WHERE ROWID IN ( SELECT MAX(ROWID) FROM TableA GROUP BY Language )
6
Eric Petroelje

副選択でRANK()関数を使用してから、ランク= 1の行をプルします。

select person, language
from
( 
    select person, language, rank() over(order by language) as rank
    from table A
    group by person, language
)
where rank = 1
2
Harper Shelby
select person, language     
from table A     
group by person, language  

一意の行を返します

0
Phil

Harperが行うように、効率のために、データを1回だけヒットする必要があります。ただし、rank()を使用したくないのは、関係を与え、さらに言語ごとではなく言語ごとにグループ化するためです。そこから、行を区別するためにorder by句を追加しますが、実際にデータを並べ替える必要はありません。これを達成するには、「nullによる順序付け」を使用します。

count(*)over(言語の順序でnullでグループ化)

0
Scott Swank