如何优雅查询first_name含至少2种等频次元音的表数据
SQL简洁实现方案
核心思路绕开穷举所有元音组合的冗余写法,通过两步校验实现需求:
- 校验字段中出现的不同元音种类数 ≥ 2
- 校验所有出现过的元音的统计次数完全相等(等价于所有次数的最大值 = 最小值)
1. MySQL 实现示例
SELECT first_name FROM your_table WHERE ( SELECT COUNT(DISTINCT vowel) = 0 OR MAX(cnt) = MIN(cnt) AND COUNT(DISTINCT vowel) >= 2 FROM ( SELECT SUBSTRING(first_name, n, 1) AS vowel, COUNT(*) AS cnt FROM (SELECT 1 AS n UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10) AS nums WHERE n <= LENGTH(first_name) AND LOWER(SUBSTRING(first_name, n, 1)) IN ('a','e','i','o','u') GROUP BY vowel ) AS vowel_counts ) = 1;
上面的写法兼容MySQL 5.7及以上版本,覆盖了绝大多数姓名长度场景,如果你的MySQL版本支持JSON_TABLE/递归CTE,还可以进一步简化长度限制的硬编码逻辑。
2. PostgreSQL 实现示例
借助PostgreSQL原生的字符串和数组处理函数,写法可以更精简:
SELECT first_name FROM your_table WHERE ( SELECT COUNT(DISTINCT vowel) = 0 OR MAX(cnt) = MIN(cnt) AND COUNT(DISTINCT vowel) >= 2 FROM ( SELECT lower(unnest(string_to_array(first_name, NULL))) AS vowel, count(*) AS cnt WHERE lower(unnest(string_to_array(first_name, NULL))) IN ('a','e','i','o','u') GROUP BY 1 ) AS vowel_counts ) IS TRUE;
方案验证
- 匹配
Alexander:拆分后元音为a、e,各出现2次,不同元音数=2≥2,最大最小次数均为2,符合条件 - 排除
Jonathan:拆分后元音为a出现2次、o出现1次,最大最小次数不相等,不符合条件
如果你的数据库支持正则替换,也可以先把非元音字符全部删除后再做统计,核心逻辑完全一致,可以根据自己使用的数据库方言灵活调整写法。
内容的提问来源于stack exchange,提问作者Georgie Manole
相关产品推荐
相关产品推荐

