首页 > 解决方案 > 根据 OR 子句条件在 SQL 中查找重复项

问题描述

采用代表 MySQL v5.6.41 数据库中产品的虚构模式:

 ------------------------------------------------
| id | name | vendor_id | vendor_sku | upc | ean |
|----|------|-----------|------------|-----|-----|
| 1  | AAAA | 2         | 5678       | 456 | 111 | [1]
| 2  | aaaa | 2         | 7878       | 789 | 222 | [1]
| 3  | bbbb | 2         | 1234       | 111 | 333 | [2]
| 4  | cccc | 2         | 1234       | 222 | 444 | [2]
| 5  | dddd | 2         | 1111       | 123 | 555 | [3]
| 6  | eeee | 2         | 2222       | 123 | 666 | [3]
| 7  | ffff | 2         | 3333       | 333 | 777 | [4]
| 8  | gggg | 2         | 4444       | 444 | 777 | [4]
| 9  | hhhh | 2         | 5555       | 555 | 888 |
| 10 | iiii | 2         | 6666       | 666 | 999 |
| 11 | jjjj | 2         | 7777       | 777 | 000 |
| 12 | kkkk | 2         | 8888       | 888 | 001 |
| 13 | llll | 2         | 9999       | 999 | 002 |
| 14 | mmmm | 2         | 0000       | 000 | 003 | 
------------------------------------------------

我正在尝试查找与以下条件之一匹配的重复行数:

  1. 相同vendor_id或相同vendor_sku
  2. 相同vendor_id和相同name(不区分大小写)
  3. 相同vendor_id或相同upc
  4. 一样vendor_id和一样ean

[n]每行旁边的符号将对应于这些行在哪个条件下重复)

到目前为止,我已经收集了这个查询,但这只会匹配条件 #1:

SELECT
    count(*)
FROM
    my_table
GROUP BY
    vendor_id, vendor_sku
HAVING 
    COUNT(*) > 1

根据这个例子,我的预期结果是 8

标签: mysqlsql

解决方案


我认为exists可能有效:

select count(*)
from my_table t
where exists (select 1
              from my_table t2
              where t2.vendor_id = t.vendor_id and
                    t2.id <> t.id and
                    (t2.vendor_sku = t.vendor_sku or
                     t2.name = t.name or
                     t2.upc = t.upc or
                     t2.ean = t.ean
                    )
             );

请注意,区分大小写取决于您的排序规则。我没有添加对 case 的显式处理(我只会使用lower()),因为不清楚这种处理是否必要。


推荐阅读