我在论坛中有一张帖子表(mybb_posts
,张贴者是username
)。
我希望所有仅发布一次的人发布的所有帖子,换句话说,就是username
列中username
是单个出现的所有行。
到目前为止,我正在使用它:
SELECT *
FROM mybb_posts
WHERE username IN
(SELECT username
FROM
(SELECT username,
count(*) COUNT
FROM `mybb_posts`
GROUP BY username) tbl1
WHERE COUNT=1)
但是三个嵌套的SELECT看起来很难看。
有没有更优雅/有效/简单的方法?我在SO和其他地方看到的所有答案都集中在获取唯一ID上。
如果要建议非标准解决方案(但最好使用标准解决方案),这是针对MySQL数据库的。
答案 0 :(得分:3)
用户名列中单个出现用户名的所有行。
这建议窗口功能:
SELECT p.*
FROM (SELECT p.*, COUNT(*) OVER (PARTITION BY p.username) as cnt
FROM mybb_posts p
) p
WHERE cnt = 1;
请注意:您的版本不需要两个嵌套的子查询。您可以使用HAVING
子句:
SELECT p.*
FROM mybb_posts p
WHERE p.username IN (SELECT p2.username
FROM mybb_posts p2
GROUP BY p2.username
HAVING COUNT(*) = 1
);
答案 1 :(得分:1)
我能想到的最可移植的解决方案是not exists
和一个相关的子查询。这适用于大多数数据库,包括不支持窗口功能的数据库(例如MySQL 5.x版本或MS Access)。这也应该是一个相当有效的选择。
为此,您需要在表中有一个主键。假设它称为post_id
,则为:
select p.*
from mybb_posts p
where not exists (
select 1
from mybb_posts p1
where p1.username = p.username and p1.post_id <> p.post_id
)
为了提高性能,您需要在(username, post_id)
上建立索引。