繁体   English   中英

如何使我的 PostgreSQL select 查询更短?

[英]How can I make my PostgreSQL select query shorter?

我正在网站上工作,我需要执行一个非常复杂的 select 查询。 我设法写了它,但它看起来对我来说太长了,我想让它更短。 这是我的查询:

select friend_id, name, surname, mail, birth_date, address
from (select friend_id, name, surname, mail, birth_date, address, count(friend_id) as rents
      from (select friend.friend_id, name, surname, mail, birth_date, address
            from friend
                     left join profile p on friend.profile_id = p.profile_id
                     left join friend_group_record fgr on friend.friend_id = fgr.friend_id
                     left join meeting m on fgr.friend_group_id = m.friend_group_id
            where m.date between '2019-09-01' and '2020-01-01') as filtered_friend_profiles
      group by friend_id, name, surname, mail, birth_date, address) as counted_friend_profiles
where counted_friend_profiles.rents >= 25;

有谁知道如何使它更短?

只做这个怎么样?

select friend.friend_id, name, surname, mail, birth_date, address
from friend
left join profile p on friend.profile_id = p.profile_id
left join friend_group_record fgr on friend.friend_id = fgr.friend_id
left join meeting m on fgr.friend_group_id = m.friend_group_id
where m.date between '2019-09-01' and '2020-01-01'
group by friend.friend_id, name, surname, mail, birth_date, address
having count(friend.friend_id) >= 25;

请参阅添加having子句。

更短? (对吗?!)

SELECT f.friend_id, name, surname, mail, birth_date, address  -- ⑤
FROM   friend f
JOIN   profile p USING (profile_id)  -- ①
JOIN   friend_group_record fgr ON f.friend_id = fgr.friend_id  -- also USING?
JOIN   meeting m ON fgr.friend_group_id = m.friend_group_id  -- also USING?
WHERE  m.date >= '2019-09-01'  -- ②
AND    m.date <  '2020-01-01'
GROUP  BY 1, 2, 3, 4, 5, 6  -- ③
HAVING count(*) >= 25;  -- ④

① 将LEFT JOIN的所有三个实例更改为[INNER] JOIN ,因为食物链( meeting )中最后一张表上的条件强制所有连接的行为无论如何都像普通连接。 (正如@wildplasser 指出的那样。)请参阅:

此外,如果连接左侧的所有表中的列名相同且不同,则USING是一种方便的短语法。 (仅返回对连接列中的一个,这与手头的查询无关。)

不知道确切的表定义,我只在第一个连接中应用了它,因为连接只剩下一个表,所以不可能有歧义。 对于持久化查询,通常仅在所涉及的列名在所有连接表中稳定且不同的情况下才可取。

② 通常,您希望排除上限,而BETWEEN是错误的工具 有关的:

③ 关于这个简短的语法:

如果 PK 列存在功能依赖关系,可能会更短。 看:

count(*)更短更快(在这种情况下等效)。 此外,可以在HAVING子句中使用,而不在SELECT列表中列出。 看:

⑤ 所有源列名都应该是表限定的,如果仅用于文档。 还避免了后来对基础表的更改造成的破坏和混乱。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM