Snowflake中如何根据指定列的重复值筛选表数据行
问题说明
现有表A,包含ID、PET、COUNTRY三个字段,示例数据如下:
| ID | PET | COUNTRY |
|---|---|---|
| 45 | DOG | US |
| 72 | DOG | CA |
| 15 | CAT | CA |
| 36 | CAT | US |
| 37 | CAT | SG |
| 12 | SNAKE | IN |
| 20 | PIG | US |
| 14 | PIG | RS |
| 33 | HORSE | IQ |
需求为筛选出所有PET字段存在重复取值的行,剔除PET取值仅出现1次的记录(示例中SNAKE、HORSE对应的行需要排除)。
你之前尝试的SQL写法存在逻辑问题:将ID、PET、COUNTRY三个字段同时作为分组依据,由于ID是每行唯一的标识,每个分组的记录数永远为1,永远无法满足HAVING COUNT(*) >1的筛选条件,因此无法得到正确结果。
正确实现方案
核心逻辑是先单独按PET维度统计每个取值对应的记录总数,再基于统计结果筛选出符合条件的原始行,有两种常用实现方式:
- 通用子查询写法,兼容所有主流SQL版本:
SELECT ID, PET, COUNTRY FROM A WHERE PET IN ( SELECT PET FROM A GROUP BY PET HAVING COUNT(*) > 1 );
- 窗口函数写法,适用于MySQL8.0+、PostgreSQL、SQL Server等支持窗口函数的数据库,大表场景下性能更好:
SELECT ID, PET, COUNTRY FROM ( SELECT ID, PET, COUNTRY, COUNT(*) OVER (PARTITION BY PET) AS pet_count FROM A ) AS tmp WHERE pet_count > 1;
结果验证
针对给出的示例数据,上述语句执行后返回结果如下,完全符合预期:
| ID | PET | COUNTRY |
|---|---|---|
| 45 | DOG | US |
| 72 | DOG | CA |
| 15 | CAT | CA |
| 36 | CAT | US |
| 37 | CAT | SG |
| 20 | PIG | US |
| 14 | PIG | RS |
内容的提问来源于stack exchange,提问作者user18466310
相关产品推荐
相关产品推荐

