如何在SQL中使用IN操作符仅获取每个指定名称的首条匹配记录?
仅获取指定名称的首条匹配记录的SQL方案
你需要从百万级的TABLE_A表中,针对Name为'12'和'23'的记录,每个名称只返回首条匹配记录(比如按ID排序的第一条),当前SQL会返回所有符合条件的记录,以下是适配不同数据库的解决方案:
一、MySQL/MariaDB 实现方式
方法1:窗口函数ROW_NUMBER()(MySQL 8.0+推荐)
通过窗口函数按Name分组,对每组内的记录按ID排序,取排序后行号为1的记录:
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID ASC) AS rn FROM TABLE_A WHERE Name IN ('12', '23') ) t WHERE rn = 1;
如果要取每组内ID最大的那条(最新记录),把ORDER BY ID ASC改成ORDER BY ID DESC即可。
方法2:子查询+LIMIT(兼容低版本MySQL)
SELECT * FROM TABLE_A WHERE Name = '12' ORDER BY ID ASC LIMIT 1 UNION ALL SELECT * FROM TABLE_A WHERE Name = '23' ORDER BY ID ASC LIMIT 1;
适合数据库版本不支持窗口函数的场景,每个名称单独查询后合并结果。
二、PostgreSQL 实现方式
方法1:DISTINCT ON(PostgreSQL专属简洁语法)
SELECT DISTINCT ON (Name) * FROM TABLE_A WHERE Name IN ('12', '23') ORDER BY Name, ID ASC;
DISTINCT ON (Name)会保留每个Name组内的第一条记录,排序条件ORDER BY Name, ID ASC决定了哪条是首条。
方法2:窗口函数ROW_NUMBER()
和MySQL写法一致:
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID ASC) AS rn FROM TABLE_A WHERE Name IN ('12', '23') ) t WHERE rn = 1;
三、SQL Server 实现方式
使用窗口函数ROW_NUMBER():
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID ASC) AS rn FROM TABLE_A WHERE Name IN ('12', '23') ) t WHERE rn = 1;
四、Oracle 实现方式
方法1:窗口函数ROW_NUMBER()
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID ASC) AS rn FROM TABLE_A WHERE Name IN ('12', '23') ) t WHERE rn = 1;
方法2:ROWNUM子查询
SELECT * FROM TABLE_A a WHERE ID = (SELECT MIN(ID) FROM TABLE_A WHERE Name = a.Name) AND a.Name IN ('12', '23');
性能优化建议
针对百万级数据,为避免全表扫描,建议创建复合索引:
CREATE INDEX idx_name_id ON TABLE_A (Name, ID);
该索引可让数据库快速定位指定Name的记录,并直接按ID排序取首条,大幅提升查询效率。
内容的提问来源于stack exchange,提问作者sensen ol
相关产品推荐
相关产品推荐

