简体   繁体   English

与选择几列不同在 JOOQ 与 MySQL 中不起作用

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

The below format of SQL query works fine in MySQL下面的 SQL 查询格式在 MySQL 中工作正常

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

in jOOQ we can either use .selectDistinct in the query or select the fields but unable to do the above.在 jOOQ 中,我们可以在查询中使用.selectDistinct或选择字段,但无法执行上述操作。

If I do select distinct(allfields), JOOQ works fine.如果我确实选择了 distinct(allfields),JOOQ 工作正常。 However, it does distinct in all the columns such as distinct(emp.id), distinct(emp.fname), distinct(emp.name)但是,它在所有列中都不同,例如 distinct(emp.id)、distinct(emp.fname)、distinct(emp.name)

Is it a bug in JOOQ or is it possible to execute in the same fashion or putting distinct with each individual column to have the same performance with respect to one column alone?它是 JOOQ 中的错误还是可以以相同的方式执行或将每个单独的列置于不同的位置以单独对一个列具有相同的性能?

Please advise.请指教。

You're thinking that you're applying the "distinct function" only on one column, but that's not what you're doing.您认为您仅在一列上应用了“不同的功能”,但这不是您要做的。 You're just parenthesising your first column, as you could have done with all the others, and even without distinct你只是把你的第一列放在括号里,就像你可以对所有其他人做的那样,即使没有distinct

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

It has no effect, even in MySQL.它没有效果,即使在 MySQL 中也是如此。 What would it even mean for the DISTINCT clause to apply to only one column? DISTINCT子句仅应用于一列意味着什么? What value would you project for the other columns?你会为其他列预测什么价值? A random one?一个随机的? For example:例如:

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

Is your expectation to produce only the first or only the second row?您期望只生成第一行还是只生成第二行?

Logical order of SQL operations SQL 操作的逻辑顺序

Notice that in SQL, the logical order of operations is, for your statement (in hypothetical syntax):请注意,在 SQL 中,对于您的语句(假设语法) ,操作的逻辑顺序是:

from employee
select id, fname, name
distinct

In other words, the DISTINCT operation "happens after" the entire SELECT operation, or projection.换句话说, DISTINCT操作“发生在”整个SELECT操作或投影之后。 Even if it seems to be part of SELECT , syntactically, it is not.即使它似乎是SELECT一部分,在语法上,它也不是。 I have also explained this in this blog post about how DISTINCT and ORDER BY are related , which is another popular source of confusion in SQL.我还在这篇关于DISTINCTORDER BY是如何相关的博客文章中解释了这一点,这是 SQL 中另一个常见的混淆来源。

A predictable way to perform TOP-1 per category queries一种按类别执行 TOP-1 查询的可预测方法

If you want to produce random values for FNAME and NAME per ID , you could use this syntax:如果要为每个ID生成FNAMENAME随机值,可以使用以下语法:

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

Beware that the values wouldn't necessarily stem from the same row.请注意,这些值不一定来自同一行。 If you want them to be from the same row, you'd have to use a subquery or window functions to run a TOP-1 per category query如果您希望它们来自同一行,则必须使用子查询或窗口函数来运行每个类别查询TOP-1

PostgreSQL DISTINCT ON PostgreSQL DISTINCT ON

Do note that PostgreSQL supports DISTINCT ON for that purpose, which works together with ORDER BY to decide which row should be produced from each "distinct group".请注意,PostgreSQL 为此支持DISTINCT ON ,它与ORDER BY一起决定应该从每个“不同组”生成哪一行。 I find that very confusing, but mentioned it here for completeness' sake.我觉得这很令人困惑,但为了完整起见,在这里提到了它。

For the record, I've answered this question also with a bit more detail here .为了记录起见, 我在这里也用更详细的方式回答了这个问题

Getting those parentheses in the result query nonetheless尽管如此,在结果查询中获取这些括号

If, for some reason, you choose to not believe me, then you can always resort to using plain SQL with jOOQ and force those parentheses in the resulting query:如果出于某种原因,您选择不相信我,那么您始终可以使用带有 jOOQ 的普通 SQL并在结果查询中强制使用这些括号:

// 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();

The output will now be as you requested in your question.输出现在将如您在问题中所要求的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM