如何自然地加入具有with子句的两个查询?

时间:2019-04-03 05:45:16

标签: postgresql

我写了两个查询,以帮助找到不同产品的最小和最大销售数量。现在,我需要使用自然联接合并这两个查询以输出一个表。

查询1:

with max_quant_table as
(with maxquant_table as
(select distinct month,prod as prod, sum(quant) as quant from sales group by month,prod)
 select month as month,prod as MOST_POPULAR_PROD, quant as  MOST_POP_TOTAL_Q
from maxquant_table)
select t2.* from
    (select month, max(MOST_POP_TOTAL_Q) maxQ FROM max_quant_table group by month order by month asc)
    t1 join max_quant_table t2 on t1.month = t2.month and (t2.MOST_POP_TOTAL_Q =maxQ)

查询2:

with min_quant_table as
(with minquant_table as
(select distinct month,prod as prod, sum(quant) as quant from sales group by month,prod)
 select month as month,prod as LEAST_POPULAR_PROD, quant as  LEAST_POP_TOTAL_Q
from minquant_table)
select t2.* from
    (select month, min(LEAST_POP_TOTAL_Q) minQ FROM min_quant_table group by month order by month asc)
    t1 join min_quant_table t2 on t1.month = t2.month and (t2.LEAST_POP_TOTAL_Q = minQ)

1 个答案:

答案 0 :(得分:1)

您正在使事情复杂化。您不需要将这两个查询联接在一起(并且实际上应该远离 natural 联接),只需要将它们组合即可。 min()max()可以在同一查询中使用,无需运行两个查询来对它们进行评估。

您也不需要嵌套CTE定义,您可以一个接一个地编写。

是这样的:

with quant_table as (
  select month, prod, sum(quant) as sum_q
  from sales 
  group by month, prod
), min_max as (
  select month, max(sum_q) as max_q, min(sum_q) as min_q
  from quant_table 
  group by month 
)
select t1.* 
from quant_table t1
  join min_max t2 
    on t2.month = t1.month 
   and t1.sum_q in (t2.min_q, t2.max_q)
order by month, prod;

条件and t1.sum_q in (t2.min_q, t2.max_q)也可以写为and (t2.max_q = t1.sum_q or t2.min_q = t1.sum_q)


通过将group bywindow functions组合在一起并在单个查询中计算总和,最小值和最大值,可以进一步简化上述操作:

with min_max as (
  select month, prod, 
         sum(quant) as sum_q,
         max(sum(quant)) over (partition by month) as max_q,
         min(sum(quant)) over (partition by month) as min_q
  from sales 
  group by month, prod
)
select month, prod, sum_q
from min_max
where sum_q in (max_q, min_q)
order by month, prod;