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でこのようなクエリを作成するにはどうすればよいですか?
書くのに最も簡単なクエリは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など)の場合、次のように使用できます。利点は、(key
とvalue
以外に)結果の他の列も選択できることです。
_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> ;
_
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を設定できます
受け入れられた回答に似ていますが、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で確認)