我想在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);
我的问题是,如何从maxCol
获取subQ
列并在join
中使用它?我的join
是这样的:
select()
.from(TBL1)
.join(subQ.asTable())
.on(TBL1.COL1.eq(subQ.asTable().field("maxCol")));
我在.on()
类型字段中的方法eq(String)不适用于参数(字段)
我该怎么办?
答案 0 :(得分:0)
这解决了问题:
select().from(TBL1).join(subQ.asTable()).on(TBL1.COL1.eq((Field<DataType>) subQ.field("maxCol")));
答案 1 :(得分:0)
如果您使用的是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
访问权限,可能会更快地运行。
如果您从任何表中按无类型名称(String
或org.jooq.Name
)访问字段,则编译器没有任何类型信息可以放在生成的Field<?>
上,这是为什么你的原始代码没有编译。
但是,您可以使用以下技术之一:
maxCol
字段引用从子查询中分解出maxCol
字段引用并将其分配给局部变量(假设它是Integer
类型,如果需要则替换):
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)));
maxCol
TBL1.COL1
列命名
在这个特定的用例中,可能不会引入任何新名称,而是重用COL1
作为名称:
Select<?> subQ = myDSL.select(DSL.max(TBL1.COL1).as(TBL1.COL1), TBL1.COL2)
.from(TBL1)
.groupBy(TBL1.COL2);
在这种情况下(如果没有不明确的COL1
列名称),您可以使用该引用从子查询中再次提取COL1
字段:
select().from(TBL1)
.join(subQ.asTable())
.on(TBL1.COL1.eq(subQ.field(TBL1.COL1)));
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)));