QueryDsl SQL-左联接子查询

时间:2019-04-08 19:14:52

标签: java mysql spring-data querydsl

我正在使用curator,并且想要QueryDsl SQL子查询。这是纯left join

中的查询
SQL

我希望将其写在SELECT usr.memberId, payoutsBbf.totalPyts FROM users usr LEFT JOIN (SELECT pyt.member_id AS mmb_id, SUM(pyt.amount) AS totalPyts FROM payout pyt WHERE pyt.payoutPeriod < '2018-01-01' GROUP BY pyt.member_id) AS payoutsBbf ON usr.id = payoutsBbf.mmb_id 中,并且将子查询保留连接到主表QueryDsl SQL几乎是很重要的,这只是整个复杂查询的一小段。

  1. 我该如何处理users部分

  2. 如何处理LEFT JOIN x ON部分中的子查询别名

2 个答案:

答案 0 :(得分:1)

我认为这对您有用。虽然有点hacky:

SQLQueryFactory sqlqf; // Should be @Autowired

QUsers qusers = new QUsers();
QPayouts qpayouts = new QPayouts();

Expression<Long> memberId = ExpressionUtils.as(qpayouts.memberId, "mmb_id");
Expression<Double> totalPayouts = ExpressionUtils.as(qpayouts.amount.sum(), "totalPayouts");

SQLQuery<Tuple> payoutsBbf = SQLExpressions.select(memberId, totalPayouts)
            .from(qpayouts)                
            .where(qpayouts.payoutPeriod.lt("2018-01-01")) // Use date object
            .groupBy(qpayouts.memberId);

final SimplePath<? extends SQLQuery> payoutsBBfPath = Expressions.path(payoutsBBfPath.getClass(), "payoutsBbf");

List<Tuple> fetch = sqlqf.select(
        qusers.memberId,                
        Expressions.path(payoutsBbf.getClass(), new PathMetadata(payoutsBBfPath, "totalPayouts", PathType.PROPERTY))
    )
    .from(qusers)
    .leftJoin(payoutsBbf, payoutsBBfPath)
    .addJoinFlag(" on payoutsBbf.mmb_id = users.id", JoinFlag.Position.BEFORE_CONDITION)
    .fetch();

请注意使用JoinFlag来使用定义为payoutsBbf的别名来指定连接列。另请注意,在Expressions.path()部分使用select()指定子列

答案 1 :(得分:0)

这就是我要做的:

final StringPath payoutsBbf = stringPath("payoutsBbf");
final String mmbId = "mmb_id";
final String totalPyts = "totalPyts";
sqlQueryFactory.select(users.memberId, stringPath(payoutsBbf, totalPyts))
    .from(users).leftJoin(
        sqlQueryFactory.select(payout.member_id.as(mmbId), member_id.amount.sum().as(totalPyts))
            .from(payout).where(payout.payoutPeriod.lt("2018-01-01")).groupBy(payout.member_id),
        payoutsBbf
    ).on(users.id.eq(stringPath(payoutsBbf, mmbId))).fetch();