当前位置: 首页 > 面试题库 >

QueryDSL-如何加入子查询的并集

沈俊晤
2023-03-14
问题内容

我正在使用QueryDSL构建SQL查询,该查询包含以联合身份加入的多个子查询。这是我查询的基础:

QTransaction t = QTransaction.transaction;
query = query.from(t).where(t.total.gt(BigDecimal.ZERO));

然后,我有几个子查询来获取与事务关联的客户端名称。我将示例缩减为两个:

SQLSubQuery subQuery = new SQLSubQuery();
subQuery = subQuery.from(t).join(t.fk462bdfe3e03a52d4, QClient.client);
ListSubQuery clientByPaid = subQuery.list(t.id, bt.paidId, QClient.client.name.as("clientname"));

subQuery = new SQLSubQuery();
subQuery = subQuery.from(t).where(t.paidId.isNull(), t.clientname.isNotNull());
ListSubQuery clientByName = subQuery.list(t.id, Expressions.constant(-1L), t.clientname.as("clientname"));

如何将它们结合在一起,并通过我的主要查询加入结合?这是我目前的尝试:

subQuery = new SQLSubQuery();
subQuery = subQuery.from(subQuery.unionAll(clientByPaid,clientByName).as("namequery"));


query = query.leftJoin(subQuery.list(
            t.id, Expressions.path(Long.class, "clientid"),
                    Expressions.stringPath("clientname")),
                    Expressions.path(List.class, "namequery"));

这样可以编译,但是在尝试运行时会在运行时生成无效的SQL query.count()。可能的错误:

  • 子查询联合的语法。
  • .as(...)命名子查询结果列的表达式与中使用的路径表达式之间的连接leftJoin

问题答案:

解决它。主要错误是我错过了on左联接中的子句,但是为了表达on条件,我在命名子查询时必须更加小心。该文档略微说明了构造访问子查询结果的路径,因此这里是示例。

联合中的第一个查询设置列名:

SQLSubQuery subQuery = new SQLSubQuery();
subQuery = subQuery.from(t).join(t.fk462bdfe3e03a52d4, QClient.client);
ListSubQuery clientByPaid = subQuery.list(t.id.as("id"), t.paidId.as("clientid"),
                                QClient.client.name.as("clientname"));

subQuery = new SQLSubQuery();
subQuery = subQuery.from(t).where(t.paidId.isNull(), t.clientname.isNotNull());
ListSubQuery clientByName = subQuery.list(t.id, Expressions.constant(-1L), 
                                  t.clientname);

现在,我需要构建一个路径表达式以引用回我的内部查询。我使用哪个类似乎并不重要,所以我选择了Void来强调这一点。

subQuery = new SQLSubQuery();
Path innerUnion = Expressions.path(Void.class, "innernamequery");
subQuery = subQuery.from(subQuery.union(clientByPaid,clientByName).as(innerUnion));

并进一步表达该on子句的路径表达。请注意,我加入list()了联合查询的一个,并使用innerUnion前面定义的路径选择了每一列。

Path namequery = Expressions.path(Void.class, "namequery");
query = query.leftJoin(subQuery.list(
                Expressions.path(Long.class, innerUnion, "id"),
                Expressions.path(Long.class, innerUnion, "clientid"),
                Expressions.stringPath(innerUnion, "clientname")),
              namequery)
          .on(t.id.eq(Expressions.path(Long.class, namequery, "id")));


 类似资料:
  • 我将以下SQL作为本机查询运行,但我想知道是否有一种方法可以在JPAQuery中运行它,以便使用元组或类实例化。 为了精确起见,我使用了别名而不是qtypes。

  • 我只想检查一下QueryDSL版本3.1.1。-是否仍然不可能与子查询连接,就像这里的答案所写的:JPQL/querydsl:join subquery and get aliased column

  • 我使用的是Spring Data JPA 1.7.1 这里有一个例子:

  • 我使用作为sql选择。现在有了要转换为QueryDSL的本机查询。它由括号中的两个OR语句组成,后跟一个应用于两个OR部分的and和查询。 我需要以下内容: 在querydsl中,我可以编写以下示例:

  • 2013年,根据@Timo Westkämper(参见QueryDSL-Add subquery into FROM语句),可以在FROM子句中包含子查询。现在看来这已经不可能了,因为JPQL规范不允许这样做: (https://docs.oracle.com/cd/e12839_01/apirefs.1111/e13946/ejb3_langref.html#ejb3_langref_subqu

  • 问题内容: 我正在使用spring-data-jpa和querydsl(3.2.3) ,有一种情况是我根据用户文件管理器/输入创建谓词集。所有这些都来了。 我的简化模型如下所示: 现在,我正在努力的是这个查询: 因此,基本上我需要以类似的格式进行子查询,该格式将获取所有公司编号并将其设置为in()表达式。 我的spring- data存储库实现了反过来扩展和的工具。 我希望答案很简单,但是我对qu