如何通过SELECT查询去除SQL中大小写不同的重复行?
解决EMAIL_ID大小写差异导致的重复记录问题
问题出在数据库默认对字符串大小写敏感,像abc@test.com和ABC@test.com会被当成不同值,直接加DISTINCT或GROUP BY根本去不掉这类重复。下面给几种解决办法:
办法1:统一大小写后用DISTINCT
把所有EMAIL_ID转成小写(或大写),这样相同邮箱不管大小写都会被视为同一值,再用DISTINCT去重:
MySQL/MariaDB/PostgreSQL/SQL Server通用写法
SELECT DISTINCT LOWER(E.EMAIL_ID) AS EMAIL_ID, T.FIRST_NAME, T.LAST_NAME, CY.COUNTRY_ID FROM PLAYER P INNER JOIN PLAYERTYPE T ON P.PLAYER_ID = T.PLAYER_ID INNER JOIN PLAYER_CONTACT C ON T.PLAYER_ID = C.PLAYER_ID INNER JOIN CONTACT_EMAIL E ON E.CONTACT_ID = C.CONTACT_ID INNER JOIN COUNTRY_TABLE CY ON P.COUNTRY_ID = CY.COUNTRY_ID WHERE CY.COUNTRY_CODE='AUS' AND T.PLAYER_TYPE IN ('NEW', 'EXE')
如果想保留原邮箱的大小写显示,只是按不区分大小写去重,就用窗口函数:
办法2:用窗口函数筛选唯一记录
这种方式可以保留原邮箱的大小写格式,同时确保同一邮箱(不区分大小写)只出现一条:
适用于MySQL 8.0+/PostgreSQL/SQL Server
SELECT EMAIL_ID, FIRST_NAME, LAST_NAME, COUNTRY_ID FROM ( SELECT E.EMAIL_ID, T.FIRST_NAME, T.LAST_NAME, CY.COUNTRY_ID, -- 按小写后的邮箱分组,每组只留第一条 ROW_NUMBER() OVER (PARTITION BY LOWER(E.EMAIL_ID) ORDER BY E.EMAIL_ID) AS rn FROM PLAYER P INNER JOIN PLAYERTYPE T ON P.PLAYER_ID = T.PLAYER_ID INNER JOIN PLAYER_CONTACT C ON T.PLAYER_ID = C.PLAYER_ID INNER JOIN CONTACT_EMAIL E ON E.CONTACT_ID = C.CONTACT_ID INNER JOIN COUNTRY_TABLE CY ON P.COUNTRY_ID = CY.COUNTRY_ID WHERE CY.COUNTRY_CODE='AUS' AND T.PLAYER_TYPE IN ('NEW', 'EXE') ) AS sub WHERE rn = 1;
ORDER BY E.EMAIL_ID可以指定保留哪一条,比如优先留小写的,或者按邮箱出现顺序选第一条,按需调整就行。
办法3:修改数据库列规则(永久解决)
如果以后不想每次查询都处理大小写,可以直接修改CONTACT_EMAIL表中EMAIL_ID列的排序规则,让它默认不区分大小写:
MySQL
ALTER TABLE CONTACT_EMAIL MODIFY COLUMN EMAIL_ID VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
(utf8mb4_general_ci里的ci就是大小写不敏感的意思)
SQL Server
ALTER TABLE CONTACT_EMAIL ALTER COLUMN EMAIL_ID VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS;
PostgreSQL
先安装citext扩展,再修改列类型:
CREATE EXTENSION IF NOT EXISTS citext; ALTER TABLE CONTACT_EMAIL ALTER COLUMN EMAIL_ID TYPE citext;
改完之后,后续用DISTINCT或GROUP BY就会自动忽略大小写差异,不用再手动转换了。
内容的提问来源于stack exchange,提问作者kakamania10
相关产品推荐
相关产品推荐

