[英]Reuse result from subquery when creating a view
在Postgresql中创建视图时,是否可以在后续子查询中重用子查询的结果?
例如,我有以下两个表:
CREATE TABLE application
(
id INT PRIMARY KEY,
name CHARACTER VARYING(255)
);
CREATE TABLE application_user
(
id INT PRIMARY KEY,
application_id INT REFERENCES application (id) ON DELETE CASCADE,
active BOOLEAN
);
-- some sample data
INSERT INTO application (id, name) VALUES
(10, 'application1'),
(20, 'application2'),
(30, 'application3');
INSERT INTO application_user (id, application_id, active) VALUES
(1, 10, true),
(2, 10, false),
(3, 20, false),
(4, 20, false),
(5, 20, false);
我需要的视图(现在)如下所示:
CREATE VIEW application_stats AS
SELECT a.name,
(SELECT COUNT(1) FROM application_user u
WHERE a.id = u.application_id) AS users,
(SELECT COUNT(1) FROM application_user u
WHERE a.id = u.application_id AND u.active = true) AS active_users
FROM application a;
这确实给了我正确的结果:
name users active_users application1 2 1 application2 3 0 application3 0 0
但是,由于我要使用两次几乎相同的查询,所以效率也很低,理想情况下,我想重用第一个查询的结果。 有一种有效的方法可以做到这一点吗?
通常用以下方式将其表示为join
/ group by
:
SELECT a.name, COUNT(au.application_id) as users,
SUM( (au.active = true)::int) as active_users
FROM application a LEFT JOIN
application_user au
ON a.name = au.application_id
GROUP BY a.name;
我很惊讶application
没有serial
主键。 但是由于您使用的是name
,所以根本不需要join
:
SELECT au.application_id, COUNT(*) as users,
SUM( (au.active = true)::int) as active_users
FROM application_user au
GROUP BY au.application_id;
这将返回至少具有一台服务器的应用程序。
你应该加入这两个表,按application_id
和使用count
与FILTER (WHERE ...)
子句只计算所需的行:
CREATE VIEW application_stats AS
SELECT a.name
count(*) AS users,
count(*) FILTER (WHERE u.active) AS active_users
FROM application a
LEFT JOIN application_user u ON a.id = u.application_id
GROUP BY a.id;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.