如何使PostgreSQL选择查询更短?

时间:2020-06-07 17:29:20

标签: sql postgresql 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;

有人知道如何使其更短吗?

2 个答案:

答案 0 :(得分:1)

怎么做?

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子句的添加。

答案 1 :(得分:1)

更短? (对吗?!)

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 is the wrong tool。相关:

③关于此简短语法:

如果PK列具有功能依赖性,则可能更短。参见:

count(*)短且快(在这种情况下等效)。另外,可以在HAVING子句中使用,而无需在SELECT列表中列出。参见:

⑤如果仅出于说明目的,所有源列名称都应为表限定的。还避免了以后对基础表的更改造成的破坏和混乱。

相关问题