在QueryDSL中使用带有“in”运算符的两个字段

时间:2014-10-22 12:03:15

标签: java sql subquery querydsl

我必须使用QueryDSL编写此查询:

select *
from table
where(field1, field2) in (
    select inner_field_1, inner_field2
    from ...
);

但是,我不知道如何在QueryDSL中使用带有“in”运算符的两个字段(field1和field2)。我一直在文档中寻找它,但我没有看到任何两个字段的例子。

这是我到目前为止所做的:

Expression<?>[] projection = {
    table.field1,
    table.field2
};

SQLSubQuery outterQuery= new SQLSubQuery()
    .from(table)
    .where([some expression].in(inneryQuery.list(projection))) // ???
    .groupBy(contentcache1.programId, contentcache1.id);

任何帮助将不胜感激

非常感谢您提前

3 个答案:

答案 0 :(得分:10)

您可以通过

表达
SQLSubQuery outerQuery = new SQLSubQuery()
    .from(table)
    .where(Expressions.list(column1, column2, ...).in(inneryQuery.list(projection))) 
    .groupBy(contentcache1.programId, contentcache1.id);

答案 1 :(得分:1)

您可以将原始查询重写为:

select *
from table, (select distinct inner_field_1, inner_field2 from ...) subquery
where field1 = subquery.field1 and field2 = subquery.field2

然后您不必使用IN运算符。

答案 2 :(得分:1)

您可以手动将row-value-expression IN谓词转换为等效的EXISTS谓词,该谓词可能适用于QueryDSL。 Some details are explained in this blog post,它基本上解释了jOOQ如何为你自动处理这种SQL转换,直接在SQL AST上运行,你会写:

DSL.using(configuration)
   .select()
   .from(TABLE)
   .where(row(TABLE.FIELD1, TABLE.FIELD2).in(
       select(INNER_FIELD1, INNER_FIELD_2)
       .from(...)
   ))

您的原始查询:

select *
from table
where(field1, field2) in (
    select inner_field_1, inner_field_2
    from ...
);

相当于这一个:

select *
from table
where exists (
    select 1
    from ...
    where table.field1 = inner_field_1 and table.field2 = inner_field2
)

...我相信你可以用QueryDSL表达(不幸的是,我不太了解API以显示实际的查询)。

关于兼容性的注意事项

无论如何,您的数据库可能不支持这种行值表达式谓词,如果您安全地使用EXISTS。至少这些数据库确实支持该谓词:

  • DB2
  • HSQLDB
  • MySQL的
  • 甲骨文
  • 的Postgres