2015-04-22 128 views
0

我有一张表,其中用户标识分为2列。 (为了解释这一点,我们通过扫描条形码来捕获参与者的ID,有时条形码扫描器功能无论如何都不起作用,所以如果条形码扫描器不起作用,我们也允许手动输入ID。 )这导致如下数据:MySQL在多列中查找重复项

+------+-----------+ 
| ID | ID_MANUAL | 
+------+-----------+ 
| A | NULL  | 
| NULL | A   | 
| B | NULL  | 
| B | NULL  | 
| NULL | C   | 
| C | NULL  | 
| NULL | D   | 
| NULL | D   | 
+------+-----------+ 

我想查找所有重复ID,考虑到两列。很容易找到仅在1列(“B”和“D”)中的重复项。但是,如何找到重复的“A”和“C”?理想情况下,查询将查找并返回所有重复项(A,B,C和D)。

谢谢!

+1

为什么手动输入不能与条形码条目进入同一列? – MuppetGrinder

+0

无论是自动还是手动输入,在同一列中都没有捕获“ID”是否有很好的理由?如果存储ID的输入方式非常重要,则可以将另一个字段存储为自动还是手动输入(如果只有这两个选项,它可能是BOOLEAN)。这看起来很糟糕的设计。 – Eilidh

回答

0

建议:名为ID m的字段,ust是唯一且不为空的。但是,如果你有这样的结构,你可以试试这个:

SELECT id 
FROM yourtable t 
WHERE id is not null 
AND 
    (SELECT COUNT(*) 
    FROM yourtable t2 
    WHERE t2.id = t.id) + 
    (SELECT COUNT(*) 
    FROM yourtable t3 
    WHERE t3.id_manual = t.id) > 1 

UNION 

SELECT id_manual 
FROM yourtable t 
WHERE id_manual is not null 
AND 
    (SELECT COUNT(*) 
    FROM yourtable t2 
    WHERE t2.id = t.id_manual) + 
    (SELECT COUNT(*) 
    FROM yourtable t3 
    WHERE t3.id_manual = t.id_manual) > 1 

你可以去Sql Fiddle

+0

完美运作,非常感谢! – user3780463

0

你可以尝试UNION ALL这里:

select id,count(*) 
from 
(
select id 
from yourtable 
union all 
select id_manual as id 
from yourtable 
) a 
group by id 
having count(*) >1; 
1

试试这个:

SELECT DUP.* FROM (SELECT ID FROM yourtable) ORI 
LEFT JOIN yourtable DUP ON DUP.ID = ORI.ID_MANUAL WHERE DUP.ID IS NOT NULL 
+0

您应该将其重写为LEFT JOIN。 –

0

尝试:

select id, count(*) 
from 
(
select id 
from data 
where id_manual is null 
union all 
select id_manual as id 
from data 
where id is null 
) a 
group by id 
having count(*) > 1; 

select id, id_manual 
from data 
group by id, id_manual 
having count(*) > 1; 
0

你可以这样做一个简单连接,使用COALESCE和DISTINCT,如果你有一个代理自动递增的主键:

SELECT DISTINCT s2.pk, s2.ID, s2.ID_MANUAL 
FROM scans s1 
JOIN scans s2 
ON COALESCE(s2.ID, s2.ID_MANUAL) = COALESCE(s1.ID, s1.ID_MANUAL) 
AND s2.pk > s1.pk 

这样就可以排除原始记录,所以你可以删除在这个结果集中返回的记录。

这是SQL Fiddle