【问题标题】:SQLAlchemy subquery in from clause without join没有连接的 from 子句中的 SQLAlchemy 子查询
【发布时间】:2013-08-16 03:10:18
【问题描述】:

我需要一点帮助。 我有以下查询,我很好奇如何用 sqlalchemy.orm 来表示它。目前我正在通过 session.execute 执行它。它对我来说并不重要,但我只是好奇。我实际上不知道的是如何将子查询放入 FROM 子句(嵌套视图)而不进行任何连接。

select g_o.group_ from (
    select  distinct regexp_split_to_table(g.group_name, E',') group_
        from (
            select array_to_string(groups, ',') group_name
            from company
            where status='active'
            and   array_to_string(groups, ',') like :term
            limit :limit
        ) g
    ) g_o
where g_o.group_ like :term
order by 1
limit :limit

由于速度问题,我需要这个子查询——在最内部的查询函数中没有限制 regexp_split_to_table 开始解析所有数据,并且只有在那之后才限制。但是我的桌子很大,我买不起。

如果不是很清楚,请追问,我会尽力的)

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    我猜这是 PostgreSQL。

    要创建子查询,请使用subquery() 方法。生成的对象可以像 Table 对象一样使用。这是您的查询在 SQLAlchemy 中的样子:

    subq1 = session.query(
        func.array_to_string(Company.groups, ',').label('group_name')
    ).filter(
        (Company.status == 'active') &
        (func.array_to_string(Company.groups, ',').like(term))
    ).limit(limit).subquery()
    
    subq2 = session.query(
        func.regexp_split_to_table(subq1.c.group_name, ',')
            .distinct()
            .label('group')
    ).subquery()
    
    q = session.query(subq2.c.group).\
        filter(subq2.c.group.like(term)).\
        order_by(subq2.c.group).\
        limit(limit)
    

    但是,您可以通过使用unnest 函数来避免一个子查询,而不是使用arrayt_to_string 将数组转换为字符串,然后使用regexp_split_to_table 将其拆分:

    subq = session.query(
        func.unnest(Company.groups).label('group')
    ).filter(
        (Company.status == 'active') &
        (func.array_to_string(Company.groups, ',').like(term))
    ).limit(limit).subquery()
    
    q = session.query(subq.c.group.distinct()).\
        filter(subq.c.group.like(term)).\
        order_by(subq.c.group).\
        limit(limit)
    

    【讨论】:

    • 一个没有明确提及的重要部分(但可以从样本中推断出来):您需要明确使用subq1.c 而不是subq1 将查询用作子查询表,否则由于缺少属性,查询将无法编译。 See this doc for details.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多