与 select 不同,JOOQ 与 MySQL 中的几列不起作用

Distinct with select few columns doesn't work in JOOQ vs MySQL

下面的 SQL 查询格式在 MySQL

中工作正常
select distinct(emp.id), emp.fname, emp.name from employee emp;

在 jOOQ 中,我们可以在查询中使用 .selectDistinct 或 select 字段但无法执行上述操作。

如果我做 select distinct(allfields),JOOQ 工作正常。但是,它在所有列中都不同,例如 distinct(emp.id)、distinct(emp.fname)、distinct(emp.name)

这是 JOOQ 中的一个错误,还是有可能以相同的方式执行,或者将 distinct 与每个单独的列放在一起,以获得与单独一列相同的性能?

请指教

您认为您只在一列上应用了 "distinct function",但这不是您正在做的。您只是将第一列括起来,就像您可以对所有其他列所做的那样,甚至没有 distinct

select (emp.id), (emp.fname), (((emp.name))) from employee emp;

即使在 MySQL 中也没有效果。 DISTINCT 子句仅应用于一列意味着什么?您预计其他列的价值是多少?一个随机的?例如:

+----+-------+------+
| ID | FNAME | NAME |
+----+-------+------+
|  1 | A     | A    |
|  1 | B     | B    |
+----+-------+------+

您期望只生成第一行还是第二行?

SQL 操作的逻辑顺序

请注意,在 SQL 中,the logical order of operations 对于您的陈述(在假设语法中)是:

from employee
select id, fname, name
distinct

也就是说,DISTINCT操作"happens after"整个SELECT操作,或者投影。即使它看起来是 SELECT 的一部分,但从句法上讲,它不是。我还在这个关于 how DISTINCT and ORDER BY are related 的博客 post 中对此进行了解释,这是 SQL.

中另一个常见的混淆来源

一种按类别查询执行 TOP-1 的可预测方式

如果您想为每个 ID 生成 FNAMENAME 的随机值,您可以使用以下语法:

select id, max(fname), max(name)
from employee
group by id

请注意,这些值不一定来自同一行。如果您希望它们来自同一行,则必须使用子查询或 window 函数来 运行 a TOP-1 per category query

PostgreSQL DISTINCT ON

请注意,PostgreSQL 为此目的支持 DISTINCT ON,它与 ORDER BY 一起决定应该从每个 "distinct group" 中生成哪一行。我觉得这很令人困惑,但为了完整起见在这里提到它。

郑重声明,I've answered this question also with a bit more detail here

仍然在结果查询中获取那些括号

如果出于某种原因,你选择不相信我,那么你总是可以使用 plain SQL 和 jOOQ 并在结果查询中强制使用这些括号:

// Static import is implied
import static org.jooq.impl.DSL.*;

ctx.selectDistinct(
        field("({0})", EMPLOYEE.ID.getDataType(), EMPLOYEE.ID),
        EMPLOYEE.FNAME,
        EMPLOYEE.NAME)
   .from(EMPLOYEE)
   .fetch();

输出现在将与您在问题中要求的一样。