web-dev-qa-db-ja.com

ある列と別の列の個別を選択するにはどうすればよいですか?

1つの列のすべての個別の値を見つけるためにSQLデータベースをクエリする必要があり、別の列の任意の値が必要です。たとえば、キーと値の2つの列がある次の表を考えてみます。

key     value
===     =====
one     test
one     another
one     value
two     goes
two     here
two     also
three   example

個別の各キーから任意に選択された1つのサンプル行を取得し、おそらくこれらの3つの行を取得します。

key     value
===     =====
one     test
two     goes
three   example

SQLでこのようなクエリを作成するにはどうすればよいですか?

32
WilliamKF

書くのに最も簡単なクエリはMySQLです(厳密なANSI設定はありません)。非標準の構造を使用します:

_SELECT key, value
FROM tableX
GROUP BY key ;
_

厳密な設定と_ONLY_FULL_GROUP_BY_がデフォルトである最近のバージョン(5.7および8.0以降)では、5.7で追加されたANY_VALUE()関数を使用できます。

_SELECT key, ANY_VALUE(value) AS value
FROM tableX
GROUP BY key ;
_

ウィンドウ関数を持つ他のDBMS(Postgres、SQL-Server、Oracle、DB2など)の場合、次のように使用できます。利点は、(keyvalue以外に)結果の他の列も選択できることです。

_SELECT key, value
FROM tableX
    ( SELECT key, value,
             ROW_NUMBER() OVER (PARTITION BY key 
                                ORDER BY whatever)     --- ORDER BY NULL
               AS rn                                   --- for example
      FROM tableX
    ) tmp 
WHERE rn = 1 ;
_

上記の古いバージョンおよびその他のDBMSの場合、ほぼすべての場所で機能する一般的な方法。 1つの欠点は、この方法では他の列を選択できないことです。もう1つは、MIN()MAX()などの集計関数が、一部のDBMSの一部のデータ型(ビット、テキスト、BLOBなど)では機能しないことです。

_SELECT key, MIN(value) AS value
FROM tableX
GROUP BY key ;
_

PostgreSQLには、使用可能な特別な非標準の_DISTINCT ON_演算子があります。オプションの_ORDER BY_は、すべてのグループからどの行を選択するかを選択するためのものです。

_SELECT DISTINCT ON (key) key, value
FROM tableX
-- ORDER BY key, <some_other_expressions> ;
_
38
ypercubeᵀᴹ

MS-SQLサーバーの場合:

;with FinalDataset as
(
    select *,
        row_number() over(partition by key order by value) as rownum
    from YourOriginalTable
)
select
   key,
   value
from FinalDataset 
where rownum = 1

同様に、2番目の結果セットにrownum = 2を設定できます

3
JP Chauhan

受け入れられた回答に似ていますが、min()またはmax()の代わりに、array_agg()を使用できます

SELECT key, (array_agg(value))[1] AS value
FROM tableX
GROUP BY key ;

オプションで配列内の値を並べ替えて、それらの最大値または最小値を選択できます。

SELECT key, (array_agg(value) ORDER BY value DESC)[1] AS value
FROM tableX
GROUP BY key ;

(PostgreSQLで確認)

2
alexkovelsky