可用版本:Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

SELECT DISTINCT ON

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

SELECT DISTINCT 的一个有用但可能有点深奥的 PostgreSQL 特定扩展是 ON 子句。使用此子句,PostgreSQL 用户可以指定不同的标准,然后从组的元组之一生成每个不同组的其他列。这通常在 SQL 中是不可能的,但是使用 ON,仍然可以访问根据 ORDER BY 子句的组中的第一个元组。一个例子

SELECT DISTINCT ON (BOOK.LANGUAGE_ID)
  BOOK.LANGUAGE_ID, BOOK.TITLE
FROM BOOK
ORDER BY BOOK.LANGUAGE_ID, BOOK.TITLE
Select<?> select1 = create.select(BOOK.LANGUAGE_ID, BOOK.TITLE)
      .distinctOn(BOOK.LANGUAGE_ID)
      .from(BOOK)
      .orderBy(BOOK.LANGUAGE_ID, BOOK.TITLE).fetch();

由于语法原因,关键字的顺序必须反转,因为 PostgreSQL 语法无法在 jOOQ 的内部 DSL 中轻松重现。很可能,您可能会发现 jOOQ 的语法更直观,因为它更清楚地分离了 SELECT 部分和 DISTINCT ON 部分。可以说,DISTINCT ON 子句应该放在 ORDER BY 之后,它逻辑上属于那里。

标准 SQL 等价形式

PostgreSQL 扩展实际上不是必需的,因为存在使用 ROW_NUMBER 过滤的标准 SQL 等价形式。在下面的示例中,我们使用标准的一个扩展,即 QUALIFY 子句,进行说明

SELECT BOOK.LANGUAGE_ID, BOOK.TITLE
FROM BOOK
QUALIFY ROW_NUMBER() OVER (PARTITION BY BOOK.LANGUAGE_ID ORDER BY BOOK.TITLE) = 1
ORDER BY BOOK.LANGUAGE_ID, BOOK.TITLE
Select<?> select1 = create.select(BOOK.LANGUAGE_ID, BOOK.TITLE)
      .from(BOOK)
      .qualify(rowNumber().over(partitionBy(BOOK.LANGUAGE_ID).orderBy(BOOK.TITLE)).eq(1))
      .orderBy(BOOK.LANGUAGE_ID, BOOK.TITLE).fetch();

方言支持

此示例使用 jOOQ

select(BOOK.LANGUAGE_ID, BOOK.TITLE).distinctOn(BOOK.LANGUAGE_ID).from(BOOK).orderBy(BOOK.LANGUAGE_ID, BOOK.TITLE)

翻译成以下特定方言的表达式

Aurora Postgres、ClickHouse、CockroachDB、DuckDB、H2、Postgres、YugabyteDB

SELECT DISTINCT ON (BOOK.LANGUAGE_ID) BOOK.LANGUAGE_ID, BOOK.TITLE
FROM BOOK
ORDER BY BOOK.LANGUAGE_ID, BOOK.TITLE

BigQuery、DB2、Databricks、Exasol、Firebird、Hana、Informix、MariaDB、MemSQL、MySQL、Oracle、Redshift、SQLDataWarehouse、SQLServer、SQLite、Snowflake、Sybase、Teradata、Trino、Vertica

SELECT t.LANGUAGE_ID, t.TITLE
FROM (
  SELECT
    BOOK.LANGUAGE_ID,
    BOOK.TITLE,
    row_number() OVER (
      PARTITION BY BOOK.LANGUAGE_ID
      ORDER BY BOOK.LANGUAGE_ID, BOOK.TITLE
    ) rn
  FROM BOOK
) t
WHERE rn = 1
ORDER BY LANGUAGE_ID, TITLE

ASE、Access、Aurora MySQL、Derby、HSQLDB

/* UNSUPPORTED */
使用 jOOQ 3.21 生成。早期 jOOQ 版本的支持可能有所不同。 在我们的网站上翻译您自己的 SQL

反馈

您对此页面有任何反馈吗? 我们很乐意听到您的意见!

The jOOQ Logo