需要帮助将带有自连接的 MySQL 查询转换为 SQLAlchemy

Posted

技术标签:

【中文标题】需要帮助将带有自连接的 MySQL 查询转换为 SQLAlchemy【英文标题】:Need help converting a MySQL query with a self join to SQLAlchemy 【发布时间】:2020-01-31 17:14:32 【问题描述】:

这是查询,我会发布到目前为止的工作,但我确定它没有用。这里的目标也是避免子查询,这是性能非常重要的情况。

我的 mysql 查询:

SELECT o.id FROM orders o
    JOIN cart_items ci ON (o.cart_id = ci.cart_id)
    LEFT JOIN cart_items cii ON (cii.cart_id = ci.cart_id AND cii.stage <> 'crowdfunding') 
    WHERE cii.cart_id IS null AND ci.stage = 'crowdfunding';

伪代码中的数据:

Order 
    id: Integer(primary_key(True))
    cart_id: Integer(foreign_key(Cart.id))

Cart 
    id: integer(primary_key(True))

CartItem 
    id: integer(primary_key(True))
    cart_id: integer(foreign_key(Cart.id))

到目前为止,我的 SQLAlchemy 查询得到了什么:

        def get_orders_for_stage_q(stage):
            join_subq = model.Session.query(ci).\
                join(
                    cii,
                    (cii.cart_id == ci.cart_id and cii.stage != stage),
                    isouter=True
                ).\
                filter(
                    cii.cart_id == None,
                    ci.stage == stage
                ).subquery()

            q = model.Session.query(model.Order.id).\
                join(join_subq, model.Order.cart_id == join_subq.c.cart_id)

            return q

编辑: 此查询为我提供了所有 orders 具有属于 cartscarts 的所有 cart_items 属于该 carts 项目的阶段 == 'crowdfunding'。

【问题讨论】:

sub-query 在哪里? 我没有,我有这个查询的一个版本,它使用子查询而不是自连接,但是这个快了大约 50%,另一个太慢了SQL炼金术。 :// 你想达到什么目的?帮助我们帮助您,并分享一些示例数据和期望的结果。 我添加了更多信息。我认为我无法再优化该查询,但如果不使用子查询,我也无法获得 SQLAlchemy 查询来达到相同的效果。 SQLAlchemy 中的子查询非常慢。 :( 【参考方案1】:

知道了,经过验证可以在我的环境中工作。 :)

            q = model.Session.query(model.Order.id).\
                join(
                    ci, model.Order.cart_id == ci.cart_id
                ).\
                join(
                    cii,
                    and_(
                        cii.cart_id == ci.cart_id,
                        cii.stage != stage
                    ),
                    isouter=True
                ).\
                filter(
                    cii.cart_id == None,
                    ci.stage == stage
                ).distinct()

【讨论】:

以上是关于需要帮助将带有自连接的 MySQL 查询转换为 SQLAlchemy的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有内连接的 sql 查询转换为 linq lambda 表达式?

如何将带有内连接语句的 Sql 查询转换为带有 Where 语句的 sql 查询(语句中没有内连接)

带有子查询的 MySQL 视图

将带有连接的 SQL 查询转换为 lambda 表达式

将 Oracle 查询转换为 MySQL 查询

可以将带有子查询的 Mysql 查询转换为 web2py DAL 吗?