I am using QueryDsl SQL
and I want to left join
a subquery. Here is the query in plain 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
I wish to write it in QueryDsl SQL
and is almost important that the subquery is left joined to the main table users
coz this is just a snippet of the whole complex query.
How do I deal with the LEFT JOIN x ON
part
How do I deal with the subquery alias in the SELECT payoutBbf.totalPyts
part
I think this will work for you. It's a bit hacky though:
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();
Note the usage of JoinFlag to specify the join column, using the alias defined as payoutsBbf
. Also note the use of Expressions.path()
to specify sub-columns in the select()
section
this is how I would do it:
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();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.