如何为一列选择不同的列和另一列中的任何列?

Wil*_*mKF 40 query

我需要查询 SQL 数据库以查找一列的所有不同值,我需要另一列中的任意值。例如,考虑下表有两列,键和值:

key     value
===     =====
one     test
one     another
one     value
two     goes
two     here
two     also
three   example
Run Code Online (Sandbox Code Playgroud)

我希望从每个不同的键中取回一个任意选择的样本行,也许得到这三行:

key     value
===     =====
one     test
two     goes
three   example
Run Code Online (Sandbox Code Playgroud)

如何在 SQL 中制定这样的查询?

ype*_*eᵀᴹ 48

最容易编写的查询是针对 MySQL(没有严格的 ANSI 设置)。它使用非标准结构:

SELECT key, value
FROM tableX
GROUP BY key ;
Run Code Online (Sandbox Code Playgroud)

在最近的版本(5.7 和 8.0+)中,严格设置 和ONLY_FULL_GROUP_BY是默认设置,您可以使用ANY_VALUE()5.7 中添加的功能:

SELECT key, ANY_VALUE(value) AS value
FROM tableX
GROUP BY key ;
Run Code Online (Sandbox Code Playgroud)

对于其他具有窗口函数的 DBMS(如 Postgres、SQL-Server、Oracle、DB2),您可以像这样使用它们。优点是您还可以选择结果中的其他列(除了keyand 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 ;
Run Code Online (Sandbox Code Playgroud)

对于上述旧版本和任何其他 DBMS,这是一种几乎适用于任何地方的通用方法。一个缺点是您无法使用此方法选择其他列。另一个就是这样聚合函数MIN()MAX()不与某些DBMS一些数据类型(如位,文本,BLOB)的工作:

SELECT key, MIN(value) AS value
FROM tableX
GROUP BY key ;
Run Code Online (Sandbox Code Playgroud)

PostgreSQL 有一个特殊的非标准DISTINCT ON操作符也可以使用。可选ORDER BY用于选择应从每个组中选择哪一行:

SELECT DISTINCT ON (key) key, value
FROM tableX
-- ORDER BY key, <some_other_expressions> ;
Run Code Online (Sandbox Code Playgroud)

  • @WilliamKF 如果“任意选择”是指“随机选择”,那么只需将 ypercube 查询中的“ORDER BYwhatever”替换为调用函数来随机化结果。 (2认同)

JP *_*han 6

对于 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
Run Code Online (Sandbox Code Playgroud)

同样,您可以为第二个结果集设置 rownum = 2