当前位置: 首页 > 知识库问答 >
问题:

jOOQ加入选择对象

江鹏
2023-03-14

我想在SQL中执行以下操作:

SELECT 
  * 
FROM 
  tbl1 t1 
  INNER JOIN 
  (SELECT MAX(col1) as maxCol, col2 FROM tbl1 t1 GROUP BY t1.col2) subQ
  ON t1.col2 = subQ.col2
  AND t1.col1 = subQ.maxCol

在jOOQ中,我将subQ存储到Select中

Select<?> subQ = myDSL.select(DSL.max(TBL1.COL1).as("maxCol"), TBL1.COL2)
                      .from(TBL1)
                      .groupBy(TBL1.COL2);

我的问题是,如何从subQ中获取maxCol列,并在join中使用它?我的连接是这样的:

select()
.from(TBL1)
.join(subQ.asTable())
.on(TBL1.COL1.eq(subQ.asTable().field("maxCol")));

我在()上出错

类型字段中的方法eq(字符串)不适用于参数(字段)

我该怎么办?

共有2个答案

濮阳国兴
2023-03-14

这就解决了问题:

select().from(TBL1).join(subQ.asTable()).on(TBL1.COL1.eq((Field<DataType>) subQ.field("maxCol")));
苏硕
2023-03-14

如果您使用的是MySQL 8.0,请不要使用子查询,而是使用窗口函数。这将是与您的查询等效的查询:

SELECT *
FROM (
  SELECT t1.*, RANK() OVER (PARTITION BY t1.col2 ORDER BY col1 DESC) rk
  FROM tbl1 t1
) t
WHERE t.rk = 1

优点是您只有一个tbl1访问权限,这可能运行得更快。

这通常也称为TOP-n查询。在其他数据库中,还有其他方法可以实现这一点,请参阅本文。

如果您从任何表中通过未类型化的名称(Stringorg.jooq.Name)访问字段,那么编译器没有任何类型信息可以放在生成的字段上

但是,您可以使用以下技术之一:

从子查询中,提取maxCol字段引用并将其分配给局部变量(假设它是整数类型,如果需要,请替换):

Field<Integer> maxCol = DSL.max(TBL1.COL1).as("maxCol");
Select<?> subQ = myDSL.select(maxCol, TBL1.COL2).from(TBL1).groupBy(TBL1.COL2);

现在,您还可以使用此引用从子查询中提取列:

Field<Integer> subQMaxCol = subQ.field(maxCol);

或直接在解决方案中内联:

select().from(TBL1)
        .join(subQ.asTable())
        .on(TBL1.COL1.eq(subQ.field(maxCol)));

在这个特定用例中,不引入任何新名称,而是将COL1重新用作名称可能是有意义的:

Select<?> subQ = myDSL.select(DSL.max(TBL1.COL1).as(TBL1.COL1), TBL1.COL2)
                      .from(TBL1)
                      .groupBy(TBL1.COL2);

在这种情况下(如果没有不明确的列名称),可以使用该引用从子查询中再次提取列1字段:

select().from(TBL1)
        .join(subQ.asTable())
        .on(TBL1.COL1.eq(subQ.field(TBL1.COL1)));

从原始解决方案中,当您从子查询中提取字段时,只需添加数据类型:

select().from(TBL1)
        .join(subQ.asTable())
        .on(TBL1.COL1.eq(subQ.field("maxCol", TBL1.COL1.getDataType())));

或者,强迫它:

select().from(TBL1)
        .join(subQ.asTable())
        .on(TBL1.COL1.eq(subQ.field("maxCol").coerce(TBL1.COL1)));

 类似资料:
  • 我正在尝试JOOQ,并试图使用连接语句从3个表(作者,书籍和文章)中进行选择。ERD如下: 我的问题如下: 我也有一个原型对象如下: (或任何其他pojo)将所有实体(作者详细信息图书列表文章列表)保存到一个对象中。我的问题是,是否有某种方法可以使用JOOQ将所有三个表映射到一个对象中。 提前谢谢。

  • 问题内容: 几个月前,我和其他人一起用PHP编写了一个简单的应用程序。在那里,我们需要根据一个用户ID和您需要从该用户ID选择的行中获取的另一个值,从多个表中执行SELECT。 我的第一个想法是创建多个SELECT并解析PHP脚本中的所有输出(使用所有mysql_num_rows()和类似的函数进行检查),但是那个家伙告诉我他会这样做。“好的没问题!” 我想,我的写作要少得多。好吧,当我发现他只用

  • 如果我的查询结果是带有原始值的单个列,是否有办法使用jooq获取它们,避免原始装箱? 例如,从表中的每本书中获取页数作为int[]。

  • 在SQL中,我可以执行以下类型的查询: 因为,没有方法。或者如果我只是想: 有没有一种方法可以使用Jooq来做到这一点?

  • 我使用jOOQ和Postgreql从表中选择枚举值。 不管怎样,我得到了一个例外: 我看到将返回

  • 问题内容: 我有3张桌子: 我想显示所有车辆名称的列表。如果,也应返回。 所以我想我将从这里开始: 返回以下内容: 但是,我现在无法将其范围缩小到所需的结果。如果使用,则没有任何变化,因为我已经在JOIN之前选择了不同的汽车ID。加入后它们才是唯一的。如果使用,则删除最后两行,所有对货车的引用都消失了。如果使用,则将第一行和最后一行合并,但是摩托车的则是任意选择的。我想要的是: 我需要一个唯一的汽