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
反馈
您对此页面有任何反馈吗? 我们很乐意听到您的意见!