QueryDSL - how to join to a union of subqueries

前端 未结 1 524
梦毁少年i
梦毁少年i 2021-01-19 01:18

I\'m building a SQL query with QueryDSL that contains several subqueries joined in a union. This is the base of my query:

QTransaction t = QTransaction.trans         


        
相关标签:
1条回答
  • 2021-01-19 01:41

    Fixed it. The main bug was that I'd missed out the on clause in the left join, but in order to express the on condition I had to be much more careful about naming the subqueries. The documentation is a little light on constructing paths to access subquery results, so here's the example.

    The first query in the union sets the column names:

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

    I now need to build a path expressions to refer back to my inner query. It doesn't seem to matter which class I use for the path, so I've picked Void to emphasize this.

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

    And a further path expression to express the on clause. Note that I join to a list() of the union query, with each column selected using the innerUnion path defined earlier.

    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")));
    
    0 讨论(0)
提交回复
热议问题