这是我正在尝试的查询,
SELECT s.id, s.name AS name,
CASE WHEN (ARRAY_AGG(tgs.status) @> '{Hard} ') THEN 'Hard'
WHEN (ARRAY_AGG(tgs.status) @> '{Soft} ') THEN 'Soft'
WHEN (ARRAY_AGG(tgs.status) @> '{Fluid} ') THEN 'Fluid'
WHEN (ARRAY_AGG(tgs.status) @> '{Gummy} ') THEN 'Gummy'
WHEN (ARRAY_AGG(tgs.status) @> '{Expired} ') THEN 'Expired'
END AS status,
COUNT(*) OVER()
FROM sweets AS s
INNER JOIN tasty_goofy_sweets AS tgs on tgs.sweet_id = s.id
GROUP BY s.id;
在实现这一点时,我的 friend 建议,我们可以使用 LEFT JOIN LATERAL 并只计算一次,而不是每次在 switch 情况下都计算 array_agg 。 即)像下面一样实现
SELECT s.id, s.name AS name,
CASE WHEN (tgs.status @> '{Hard} ') THEN 'Hard'
WHEN (tgs.arr_status @> '{Soft} ') THEN 'Soft'
WHEN (tgs.arr_status @> '{Fluid} ') THEN 'Fluid'
WHEN (tgs.arr_status @> '{Gummy} ') THEN 'Gummy'
WHEN (tgs.arr_status @> '{Expired} ') THEN 'Expired'
END AS status,
COUNT(*) OVER()
FROM sweets AS s
LEFT JOIN LATERAL ( SELECT ARRAY_AGG(tgs.status) AS arr_status FROM tasty_goofy_sweets tgs WHERE tgs.sweet_id = s.id
) AS tgs ON TRUE
GROUP BY s.id;
但我不确定 Postgres 是否每次都会计算 ARRAY_AGG
值,我们如何确定哪种方法更好?我尝试查看这两个查询的解释分析,后一个查询涉及的行数比前者多。但我不明白为什么会这样?
我直觉地觉得前一种方法更好,但是有人可以推理出哪种方法更好吗?为什么或者我要求太多了?
最佳答案
Postgres 最有可能会优化掉多个 array_agg()
,仅计算一次并在每次比较中重用结果。这是非常简单的查询优化,数据库应该很容易发现。
不过,我建议通过使用条件聚合来简化查询。您不需要聚合到数组中只是为了检查给定值是否存在:
select
s.id,
s.name
case
when count(*) filter(where status = 'Hard') > 0 then 'Hard',
when count(*) filter(where status = 'Soft') > 0 then 'Soft',
when count(*) filter(where status = 'Fluid') > 0 then 'Fluid'
when count(*) filter(where status = 'Gummy') > 0 then 'Gummy',
when count(*) filter(where status = 'Expired') > 0 then 'Expired'
end status,
count(*) over() cnt
from sweets s
inner join tasty_goofy_sweets AS tgs on tgs.sweet_id = s.id
group by s.id;
您也可以使用横向连接和条件排序来表达这一点,而无需聚合:
select
s.id,
s.name,
tgs.status,
count(*) over() cnt
from sweets s
cross join lateral (
select status
from tasty_goofy_sweets as tgs
where tgs.sweet_id = s.id
order by case status
when 'Hard' then 1
when 'Soft' then 2
when 'Fluid' then 3
when 'Gummy' then 4
when 'Expired' then 5
end
limit 1
) tgs
关于sql - Postgres : If we select a computed column multiple times, Postgres会一次又一次地计算它吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62375744/