QueryDsl SQL - Left 加入一个子查询
QueryDsl SQL - Left Join a subquery
我正在使用 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
中并且子查询与主查询保持连接几乎很重要 table users
因为这只是整个复杂查询的一个片段.
如何处理LEFT JOIN x ON
部分
如何处理SELECT payoutBbf.totalPyts
部分的子查询别名
我认为这对你有用。虽然有点老套:
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()
部分中的子列
我会这样做:
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();
我正在使用 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
中并且子查询与主查询保持连接几乎很重要 table users
因为这只是整个复杂查询的一个片段.
如何处理
LEFT JOIN x ON
部分如何处理
SELECT payoutBbf.totalPyts
部分的子查询别名
我认为这对你有用。虽然有点老套:
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()
部分中的子列
我会这样做:
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();