我在表“user”中有2个整数字段:leg_count和leg_length。第一个存储用户的腿数,第二个存储它们的总长度。
属于用户的每条腿都存储在单独的表中,只要典型的互联网用户可以有零到无限的腿:
CREATE TABLE legs (
user_id int not null,
length int not null
);
我想在一个查询中重新计算所有用户的统计信息,因此我尝试:
UPDATE users SET
leg_count = subquery.count, leg_length = subquery.length
FROM (
SELECT COUNT(*) as count, SUM(length) as length FROM legs WHERE legs.user_id = users.id
) AS subquery;
并获取“FROM中的子查询不能引用相同查询级别的其他关系”错误。
所以我必须这样做
UPDATE users SET
leg_count = (SELECT COUNT(*) FROM legs WHERE legs.user_id = users.id),
leg_length = (SELECT SUM(length) FROM legs WHERE legs.user_id = users.id)
是什么让数据库为每一行执行2个SELECT,但是,所需数据可以在一个SELECT中计算:
SELECT COUNT(*), SUM(length) FROM legs;
是否可以优化我的UPDATE查询以仅使用一个SELECT子查询?
我使用PostgreSQL,但我相信,任何SQL方言都存在解决方案。
TIA。
答案 0 :(得分:7)
我愿意:
WITH stats AS
( SELECT COUNT(*) AS cnt
, SUM(length) AS totlength
, user_id
FROM legs
GROUP BY user_id
)
UPDATE users
SET leg_count = cnt, leg_length = totlength
FROM stats
WHERE stats.user_id = users.id
答案 1 :(得分:3)
您可以使用PostgreSQL的extended update syntax:
update users as u
set leg_count = aggr.cnt
, leg_length = aggr.length
from (
select legs.user_id
, count(*) as cnt
, sum(length) as length
from legs
group by
legs.user_id
) as aggr
where u.user_id = aggr.user_id