SQL多重复行检测

时间:2011-10-10 00:01:57

标签: sql duplicates

我正在尝试确定一种正确的方法来隔离表中具有2列相同值的行。

有两个表,一个(姓名)带有人的姓名和身份证,另一个(国家)有人的身份证和国家。我使用内连接加入两个表,现在新表列包含ID,名字,姓氏和国家。如果我想找到一对姓氏相同且来自同一个国家的人,为什么不是

select ID, FName, LName, Nation
from (Name inner join Nation on Name.ID = Nation.ID)
group by Name, Nation
having count(Name) > 1 and count(Nation) > 1

工作?

我的目标是将结果作为一个包含列的表:

ID ------- First --------------- Last --------- Nation

其中姓氏和国家将是相同的对,而名字将是不同的。

我觉得这个小组不合适,但是还有另一种方法吗?谢谢你的帮助。

3 个答案:

答案 0 :(得分:2)

如果您使用的是MS SQL Server:

select
    *
from
(
    select 
        Name.*, 
        Nation.Nation, 
        cnt = count(*) over(partition by LName, Nation) 
    from Name
    join Nation on Nation.ID = Name.ID
) t
where cnt > 1

答案 1 :(得分:1)

试试这个:

SELECT * FROM (
  SELECT Name.ID, Name.FName, Name.LName, Nation.Nation
  FROM Name
  INNER JOIN Nation ON (Name.ID = Nation.ID)
) a
INNER JOIN (
  SELECT Name.ID, Name.FName, Name.LName, Nation.Nation
  FROM Name
  INNER JOIN Nation ON (Name.ID = Nation.ID)
) b ON (a.LName = b.LName AND a.Nation = b.Nation)
WHERE a.ID < b.ID

答案 2 :(得分:1)

正如Simon Righarts暗示的那样,设计上的某些东西是不对的。

场景1)

如果名称可以包含多个国家,则您将有3个表格实现n:m关系。

CREATE TABLE name (name_id int, name text, ...);
CREATE TABLE nation (nation_id int, nation text, ...);
CREATE TABLE nationality (name_id int references name(name_id)
            ,nation_id int references nation(nation_id)
            ... );

查询方案:

SELECT a.name_id, a.fname, a.lname, n.nation
  FROM name a
  JOIN nationality na USING (name_id)
  JOIN nation n USING (nation_id)
  JOIN (
   SELECT a.lname, na.nation_id
     FROM name a
     JOIN nationality na USING (name_id)
    GROUP BY 1,2
   HAVING count(*) > 1) x USING (lname, nation_id)

场景2)

如果某个名称只能包含一个国家/地区,则表nation_id中会有一列name

CREATE TABLE name (name_id int
                  ,name text
                  ,nation_id int references nation(nation_id), ...);
CREATE TABLE nation (nation_id int, nation text, ...);

查询此方案:

SELECT a.name_id, a.fname, a.lname, n.nation
  FROM name a
  JOIN nation n USING (nation_id)
  JOIN (
   SELECT a.lname, a.nation_id
     FROM name a
    GROUP BY 1,2
   HAVING count(*) > 1) x USING (lname, nation_id);

此处包含所有多次出现,而不只是“对” - 假设您的意思。

您的实际说明不适合任何一种情况。