【问题标题】:sqlalchemy using INTERSECT and UNNEST使用 INTERSECT 和 UNNEST 的 sqlalchemy
【发布时间】:2017-03-14 23:00:10
【问题描述】:

我正在尝试将原始 SQL 转换为 sqlalchemy 核心/orm,但我遇到了一些困难。这是 SQL:

SELECT 
    (SELECT UNNEST(MyTable.my_array_column) 
     INTERSECT 
     SELECT UNNEST(ARRAY['VAL1', 'VAL2']::varchar[])) AS matched
FROM 
    MyTable
WHERE 
    my_array_column && ARRAY['VAL1', 'VAL2']::varchar[];

以下查询给了我一个 FROM 子句,我在嵌套的 SELECT 中不需要它:

matched = select([func.unnest(MyTable.my_array_column)]).intersect(select([func.unnest('VAL1', 'VAL2')]))

# SELECT unnest(MyTable.my_array_colum) AS unnest_1 
# FROM MyTable INTERSECT SELECT unnest(%(unnest_3)s, %(unnest_4)s) AS unnest_2

如何告诉select 不包含FROM 子句?请注意,func.unnest() 只接受一列。所以我不能使用func.unnest('my_array_column')

【问题讨论】:

    标签: python sql postgresql orm sqlalchemy


    【解决方案1】:

    在子查询中引用封闭查询的表是correlation 的过程,SQLAlchemy 尝试自动执行该过程。在这种情况下,我相信它不太有效,因为您的 INTERSECT 查询是“可选择的”,而不是标量值,SQLAlchemy 尝试将其放入 FROM 列表而不是 SELECT 列表中。

    解决方案是双重的。我们需要通过应用label 使SQLAlchemy 将INTERSECT 查询放入SELECT 列表中,并使其正确关联MyTable

    select([
        select([func.unnest(MyTable.my_array_column)]).correlate(MyTable)
        .intersect(select([func.unnest('VAL1', 'VAL2')]))
        .label("matched")
    ]).select_from(MyTable)
    
    # SELECT (SELECT unnest("MyTable".my_array_column) AS unnest_1 INTERSECT SELECT unnest(%(unnest_3)s, %(unnest_4)s) AS unnest_2) AS matched 
    # FROM "MyTable"
    

    【讨论】:

    • 太棒了。谢谢。
    猜你喜欢
    • 2015-05-29
    • 2011-08-20
    • 2011-04-25
    • 2015-11-23
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 2020-09-07
    相关资源
    最近更新 更多