Sql 创建视图时重用子查询的结果
在postgresql中创建视图时,是否可以在后续子查询中重用子查询的结果 例如,我有以下两个表:Sql 创建视图时重用子查询的结果,sql,postgresql,Sql,Postgresql,在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 DELE
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
名称用户活动用户
应用程序1 2 1
应用程序2 3 0
应用程序3 0
然而,这也是非常低效的,因为我使用了两次几乎相同的查询,理想情况下,我希望重用第一次查询的结果。有没有一种有效的方法可以做到这一点?这通常表示为一个
加入/分组:
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;
我很惊讶应用程序
没有串行
主键。但是由于您使用的是名称
,因此可能根本不需要加入
:
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\u id
分组,并使用count
和筛选器(其中…
子句)仅计算所需的行:
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;
似乎是CTE(带查询的)的一个很好的用例。为了简洁起见,我排除了第一个表的序列id,但我发现这会带来不同,我的缺点。然而,我尝试了您的第一个解决方案,但没有得到“application3”活动用户的结果(application3没有任何用户,因此应该显示用户:0,活动用户:0)啊,我猜您的意思是将计数(au.active=true)为活动用户
,然后它就可以工作了。问题是,这仍然比我正在使用的重复联接慢,因为我不使用左联接。然而,我问的问题可能不清楚这一点,所以我想我应该问一个新的问题。