如何从SQL数据表中筛选出在所有ArticleId中均出现的Name及其对应的NameId?
如何筛选在所有ArticleId中都出现的Name及对应NameId
我来分享几种靠谱的SQL实现方法,完美匹配你的需求——找出那些在每一个ArticleId里都有记录的Name和对应的NameId。
先明确场景与数据
假设我们有一张表,结构和示例数据如下:
表结构
CREATE TABLE YourArticleTable ( ArticleId INT, Name VARCHAR(100), NameId INT );
示例数据
| ArticleId | Name | NameId |
|---|---|---|
| 1 | a | 100 |
| 2 | a | 100 |
| 3 | a | 100 |
| 2 | b | 200 |
| 4 | a | 100 |
| 1 | c | 300 |
| 4 | g | 400 |
| 1 | h | 500 |
| 2 | h | 500 |
| 3 | h | 500 |
| 4 | h | 500 |
你的需求很清晰:要找出像a(100)、h(500)这样,在所有ArticleId(1、2、3、4)中都存在的组合,排除只出现在部分ArticleId里的b、c、g。
几种实用的解决方案
方法1:分组统计 + 匹配总ArticleId数(最通用)
这是最直观且兼容性最好的方法,几乎所有数据库都支持。核心逻辑是:
- 先算出表中一共有多少个不重复的ArticleId
- 按
Name和NameId分组,统计每组覆盖的不同ArticleId数量 - 当分组的数量等于总ArticleId数时,就是符合条件的记录
用子查询实现的版本:
SELECT Name, NameId FROM YourArticleTable GROUP BY Name, NameId HAVING COUNT(DISTINCT ArticleId) = ( SELECT COUNT(DISTINCT ArticleId) FROM YourArticleTable );
如果想用更清晰的CTE(公共表达式)写法(适合MySQL 8+、PostgreSQL等):
WITH TotalUniqueArticles AS ( SELECT COUNT(DISTINCT ArticleId) AS total_count FROM YourArticleTable ) SELECT Name, NameId FROM YourArticleTable, TotalUniqueArticles GROUP BY Name, NameId HAVING COUNT(DISTINCT ArticleId) = total_count;
方法2:窗口函数写法(更高效,适合新版本数据库)
如果你的数据库支持窗口函数(比如MySQL 8.0+、SQL Server、PostgreSQL),可以用这种更高效的方式,避免重复扫描表:
WITH ArticleCoverage AS ( SELECT Name, NameId, -- 统计当前Name-NameId组合覆盖的不同ArticleId数 COUNT(DISTINCT ArticleId) OVER (PARTITION BY Name, NameId) AS group_coverage, -- 统计全局所有不重复的ArticleId数 COUNT(DISTINCT ArticleId) OVER () AS total_articles FROM YourArticleTable ) -- 去重后筛选符合条件的记录 SELECT DISTINCT Name, NameId FROM ArticleCoverage WHERE group_coverage = total_articles;
方法3:关联子查询(适合理解基础逻辑)
如果你想更直观地理解逻辑,可以用关联子查询,逐个验证每个Name-NameId组合是否覆盖了所有ArticleId:
SELECT DISTINCT t1.Name, t1.NameId FROM YourArticleTable t1 WHERE ( -- 统计当前Name-NameId组合覆盖的ArticleId数量 SELECT COUNT(DISTINCT ArticleId) FROM YourArticleTable t2 WHERE t2.Name = t1.Name AND t2.NameId = t1.NameId ) = ( -- 全局总ArticleId数量 SELECT COUNT(DISTINCT ArticleId) FROM YourArticleTable );
为什么这些方法能生效?
所有方法的核心逻辑都是验证每个Name-NameId组合覆盖的ArticleId数量,等于表中所有不重复的ArticleId总数。只有当一个组合在每一个ArticleId里都有记录时,它的覆盖数才会等于总数量,这样就能精准筛选出你要的结果。
内容的提问来源于stack exchange,提问作者Arie
相关产品推荐
相关产品推荐

