选择列值唯一的记录

时间:2020-07-19 12:23:40

标签: sql

我在论坛中有一张帖子表(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数据库的。

2 个答案:

答案 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)上建立索引。

相关问题