如何在Postgresql中使用一个Select语句嵌套到另一个Select语句中进行查询

7

我必须在Postgresql的另一个Select中执行此查询:

SELECT COUNT(tn.autoship_box_transaction_id) 
FROM memberships.autoship_box_transaction tn 
WHERE tn.autoship_box_id = b.autoship_box_id

我必须使用WITH子句吗?

2
你能否分享一下你计划如何应用这个查询?有几种方法可以组合SQL查询,CTE(又称WITH子句)肯定是其中之一。 - Jim Jones
2个回答

7
只要查询产生单个数据元素,您就可以将其用作属性的替代品:
SELECT (
          SELECT COUNT(tn.autoship_box_transaction_id) 
            FROM memberships.autoship_box_transaction tn 
           WHERE tn.autoship_box_id = b.autoship_box_id
       ) AS cnt
     , other_column
  FROM wherever
     ;

请查看这个SQL fiddle,演示了使用情况。
如果数据库引擎实际迭代结果集并对遇到的每个记录执行查询,则此方法通常会带来性能惩罚。
数据库引擎的优化器可能足够聪明以避免额外的成本(在fiddle的玩具示例中应该如此),但是您必须查看解释计划以确保。
请注意,这主要是与“相关子查询”有关的问题,即嵌入式查询依赖于嵌入式查询。您的示例似乎属于这种类型,因为您使用了一个未在任何地方定义的表别名b
可能有将子选择移动到from子句的选项(请注意:警惕:此语句仅用于说明目的;您必须根据自己的用例进行调整,我只是猜测)。
SELECT stats.cnt
     , b.other_column
  FROM b_table b
  JOIN (
          SELECT COUNT(tn.autoship_box_transaction_id) cnt
               , tn.autoship_box_id
            FROM memberships.autoship_box_transaction tn 
        GROUP BY tn.autoship_box_id
       ) stats
    ON (stats.autoship_box_id = b.autoship_box_id)
     ;

我尝试了这个,它非常有效。但是当我在第一个Select中添加第二个查询时,我无法添加第二个JOIN:JOIN staging.memberships_autoship a ON a.id = b.autoship_id选择stats.cnt2、stats2.cnt3、stats1.cnt1 从staging.memberships_autoship_box b中加入 (选择COUNT(bn.autoship_box_id)cnt1,bn.autoship_box_id 从staging.memberships_autoship_box bn 按bn.autoship_box_id分组 )stats1 ON(stats1.autoship_box_id = a.id) - Julie Levesque

6
有两种选择。你可以使用with子句,像这样:

WITH some_count AS (
   SELECT COUNT(tn.autoship_box_transaction_id) 
   FROM memberships.autoship_box_transaction tn 
   WHERE tn.autoship_box_id = b.autoship_box_id
)
SELECT * FROM some_count;

第二个选项是使用子查询,像这样:

SELECT
  *
FROM
  (
    SELECT COUNT(tn.autoship_box_transaction_id) 
    FROM memberships.autoship_box_transaction tn 
    WHERE tn.autoship_box_id = b.autoship_box_id
  );

为什么这个查询的结果总是1:SELECT stats1.cnt1 FROM staging.memberships_autoship_box b JOIN staging.memberships_autoship a ON a.id = b.autoship_box_id JOIN ( SELECT COUNT(bn.autoship_box_id) cnt1,bn.autoship_box_id FROM staging.memberships_autoship_box bn GROUP BY bn.autoship_box_id ) stats1 ON (stats1.autoship_box_id = a.id) - Julie Levesque

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接