【问题标题】:Combine CTE along with an IN, in PostgreSQL在 PostgreSQL 中结合 CTE 和 IN
【发布时间】:2019-02-13 02:07:38
【问题描述】:

所以我在 PostgreSQL 10 中有这个简单的查询。

with bunch_of_things as (
    select vans_id from shoes where adidas_id = 1
)

select * from vans where vans.id in (bunch_of_things) ;

我收到一个错误column "bunch_of_things" does not exist

我知道我可以将第一个选择放在第二个查询的括号内,以定义 IN 部分

但是由于我会在同一个事务中多次使用第一个查询的结果,所以我不想多次执行同一个查询。

那么我怎样才能使 IN 与 CTE 一起工作?

(如果这不可能,我怎样才能获得一次查询的结果并在事务中多次使用它们?)

谢谢

【问题讨论】:

    标签: postgresql transactions common-table-expression postgresql-10 sql-in


    【解决方案1】:

    CTE 的名称就像一个表格,所以你应该做一个选择

    with bunch_of_things as (
        select vans_id from shoes where adidas_id = 1
    )
    
    select * from vans where vans.id in (select vans_id from bunch_of_things);
    

    但是您需要考虑几件事情。

    首先,EXISTS 在性能方面通常比IN 更好

    with bunch_of_things as (
        select vans_id from shoes where adidas_id = 1
    ) 
    select * 
      from vans v
    where EXISTS (
        select 1
        from bunch_of_things b
        where b.vans_id = v.id
    )
    

    其次,在 postgres 10 及以下 CTE 中是一个性能围栏,因此 postgres 无法整体优化查询(但是 might 更改)。在某些情况下,这可能是控制查询执行的有用方法,并且绝对是您应该考虑的事情。

    在事务中执行查询和重用结果的另一种方法是使用临时表,如下所示:

    CREATE TEMPORARY TABLE bunch_of_things (vans_id integer)
    ON COMMIT DROP;
    
    INSERT INTO bunch_of_things (vans_id)
    SELECT vans_id FROM shoes where adidas_id = 1;
    

    然后照常使用表格:

    select * 
      from vans v
    where EXISTS (
        select 1
        from bunch_of_things b
        where b.vans_id = v.id
    )
    

    【讨论】:

      【解决方案2】:

      这总是很慢,因为在 PostgreSQL 中,CTE 是一个优化栅栏。

      你会想要这样的东西,

      SELECT *
      FROM vans
      WHERE EXISTS (
          SELECT
          FROM shoes
          WHERE adidas_id = 1
            AND vans_id = vans.id
      )
      

      这样会快很多。

      【讨论】:

      • 感谢您的提示。但我会多次使用嵌套子查询。那么如果我每次都定义/执行它会更快吗?谢谢
      猜你喜欢
      • 2013-05-27
      • 2011-03-19
      • 2011-04-10
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      相关资源
      最近更新 更多