如何反转连接顺序以使用子查询与 sqlalchemy 正确连接?

Posted

技术标签:

【中文标题】如何反转连接顺序以使用子查询与 sqlalchemy 正确连接?【英文标题】:How can I reverse the join order to get a right join with sqlalchemy using a subquery? 【发布时间】:2020-10-23 08:36:41 【问题描述】:

我正在尝试使用 Flask-SQLAlchemy ORM 创建以下(非常简化的)SQL 语句

SELECT TableA.attr
FROM (SELECT DISTINCT TableB.a_id FROM TableB) AS TableB
LEFT JOIN TableA
ON TableA.id = TableB.a_id 

为了实现这一点,我使用了以下 SQLAlchemy 语句

sq = db.session.query(distinct(TableB.a_id).label('a_id')).subquery()
results = db.session.query(TableA.attr).join(sq, sq.c.a_id==TableA.id, isouter=True).all()

这可行,但是它不是将我的子查询 TableB(左)与 TableA(右)连接起来,而是将 TableA 与 TableB 连接起来。

SELECT TableA.attr
FROM TableA
LEFT JOIN (SELECT DISTINCT TableB.a_id FROM TableB) AS TableB
ON TableB.a_id = TableA.id 

由于我知道 SQLAlchemy 没有正确的连接,我将不得不以某种方式颠倒顺序,同时仍然得到 TableA.attr 作为结果,我无法弄清楚如何使用子查询来做到这一点。

【问题讨论】:

x right join y on c = y left join x on c (忽略列顺序) 这是一个常见问题。请在考虑发布之前阅读您的教科书和/或手册和谷歌任何错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有和没有您的特定字符串/名称和站点:***.com 和标签;阅读许多答案。如果您发布问题,请使用一个短语作为标题。反映你的研究。请参阅How to Ask 和投票箭头鼠标悬停文本。 ***.com/questions/11400307/… 【参考方案1】:

这个问题的答案确实是 select_from() 方法。 IE。我的问题的实际解决方案是以下语句:

sq = db.session.query(distinct(TableB.a_id).label('a_id')).subquery()
results = db.session.query(TableA.attr) \
                    .select_from(sq) \
                    .join(TableA, TableA.id==sq.c.a_id, isouter=True).all()

一般来说:select_from() 方法获取连接的左侧部分。 join() 获取正确的部分作为它的第一个参数。

【讨论】:

以上是关于如何反转连接顺序以使用子查询与 sqlalchemy 正确连接?的主要内容,如果未能解决你的问题,请参考以下文章

子查询与连接

如何将子查询转换为连接以获得快速结果?

左连接与子查询的性能问题以找出最新日期

MSSQL之五 连接查询与子查询

如何强制连接顺序以提高 MYSQL 中的查询性能?

MySQL5.7-连接查询子查询关键字顺序存储引擎