如何根据MySQL中不同列的值删除重复记录?

时间:2017-10-06 20:11:43

标签: mysql sql select join duplicates

我有几个SQL表的查询:

enter image description here

我想从查询结果中过滤重复项,其中列id具有多个相同的值。在这个例子中,我们可以看到有两个id = 1(名字Miriam)。在这里,我想保留pcs = 2的记录,Miriam的第二条记录我不想在查询结果中使用它。在过滤的情况下,密钥将基于pcs列的值。

enter image description here

我怎样才能做到这一点?我的疑问是:

SELECT 
`periode_class_members`.`id`, 
`classes`.`id` AS `class`, 
`periode_class_members`.`periode`, 
`user`.`firstname` AS `firstname`, 
`user`.`lastname` AS `lastname`, 
`periode_class_members`.`status`,
`periode_class_subjects`.`id` AS pcs 
FROM `periode_class_subject_members` 
LEFT JOIN `periode_class_members` 
ON periode_class_subject_members.periode_class_member = periode_class_members.id 
RIGHT JOIN `periode_class_subjects` 
ON periode_class_subject_members.periode_class_subject = periode_class_subjects.id 
JOIN `classes` 
ON periode_class_members.class = classes.id 
LEFT JOIN `user` 
ON periode_class_members.user = user.id
where `classes`.`id` = 1;

4 个答案:

答案 0 :(得分:5)

SQL - 无视图

SELECT *
FROM 
(<<your query>>) AS sub1
WHERE NOT EXISTS
 (SELECT *
  FROM
  (<<your query>>) AS sub2
  WHERE id = sub1.id
    AND pcs <> sub1.pcs
    AND pcs = 2);

...在两个地方插入<<your query>> - 为简洁起见,此处省略。

SQL - 包含观看次数

与上述类似,但查询只需要插入一次:

CREATE VIEW vw_unfiltered_query AS
<<your query>>;

CREATE VIEW vw_filtered_query AS
SELECT *
FROM vw_unfiltered_query AS sub1
WHERE NOT EXISTS
 (SELECT *
  FROM vw_unfiltered_query AS sub2
  WHERE id = sub1.id
    AND pcs <> sub1.pcs
    AND pcs = 2);

<强>演示

以下演示使用上述两种方法显示过滤前后的结果。 (为简单起见,它使用预先填充的表中的简单SELECT语句来代替您的查询。)

http://rextester.com/MXZDDJ39435

<强>解释

WHERE NOT EXISTS确保只包含行,其中没有另一行具有相同的id但不同的pcs值等于2。

答案 1 :(得分:0)

有几种技巧。关键是首先要有一个过滤的唯一结果列表,然后添加导致问题的列。 (附带规则)。

您可以下载子查询中的人员列表并稍后附加角色,您可以在子查询(1)中下载角色,也可以在子查询(2)中对角色进行分组。

所以你可以:

/v2/accounts/{accountId}/tab_definitions

OR(非常糟糕的例子,不要在制作时这样做)

SELECT 
`periode_class_members`.`id`, 
`classes`.`id` AS `class`, 
`periode_class_members`.`periode`, 
`user`.`firstname` AS `firstname`, 
`user`.`lastname` AS `lastname`, 
`periode_class_members`.`status`,
(SELECT min(`periode_class_subjects`.`id`) FROM periode_class_subjects WHERE periode_class_subject_members.periode_class_subject = periode_class_subjects.id GROUP BY `periode_class_subjects`.`id`) AS pcs 
FROM `periode_class_subject_members` 
LEFT JOIN `periode_class_members` 
ON periode_class_subject_members.periode_class_member = periode_class_members.id 
RIGHT JOIN `periode_class_subjects` 
JOIN `classes` 
ON periode_class_members.class = classes.id 
LEFT JOIN `user` 
ON periode_class_members.user = user.id
where `classes`.`id` = 1;

我建议扩大子查询的知识。

答案 2 :(得分:0)

SELECT  pcm.`id`,
        c.`id` AS `class`,
        pcm.`periode`,
        u.`firstname`, u.`lastname`,
        pcm.`status`,
        MIN(pcs.`id`) AS pcs
    FROM  `periode_class_subject_members` AS pcsm
    LEFT JOIN  `periode_class_members` AS pcm
          ON pcsm.periode_class_member = pcm.id
    RIGHT JOIN  `periode_class_subjects` AS pcs
           ON pcsm.periode_class_subject = pcs.id
    JOIN  `classes` AS c  ON pcm.class = c.id
    LEFT JOIN  `user` AS u  ON pcm.user AS u = u.id
    where  c.`id` = 1
    GROUP BY  pcm.`id`, c.`id`,
              pcm.`periode`,
              u.`firstname`,
              u.`lastname`, pcm.`status` ;

两个重大变化是MIN并添加了GROUP BY

如果MIN不是正确的算法,那么请更改为其他内容。

GROUP BY列表与SELECT中的其他列相同。

我冒昧为每张桌子提供更短的别名。

答案 3 :(得分:0)

如果pcs字段的最小值为2,那么以下查询应该可以完成工作。

select id,class,periode,firstname,lastname,status,(Select pcs from unfiltered un
    where un.id = unfiltered.id
    order by pcs limit 1) as pcs 
from 
(your query)
group by id;

以上查询成功运行。我没有添加您的查询,以使您了解我使用的逻辑。请查看演示here

现在,我将在上面的解决方案中添加您的查询,并相应地修改列名。

Select temp.id,temp.class,temp.periode,
       temp.firstname,temp.lastname,temp.status,
       (Select pcs from temp t
           where t.id = temp.id
        order by t.pcs limit 1) as pcs 
from 
   (SELECT 
`periode_class_members`.`id` AS id, 
`classes`.`id` AS `class`, 
`periode_class_members`.`periode`, 
`user`.`firstname` AS `firstname`, 
`user`.`lastname` AS `lastname`, 
`periode_class_members`.`status`,
`periode_class_subjects`.`id` AS pcs 
FROM `periode_class_subject_members` 
LEFT JOIN `periode_class_members` 
ON periode_class_subject_members.periode_class_member = periode_class_members.id 
RIGHT JOIN `periode_class_subjects` 
ON periode_class_subject_members.periode_class_subject = periode_class_subjects.id 
JOIN `classes` 
ON periode_class_members.class = classes.id 
LEFT JOIN `user` 
ON periode_class_members.user = user.id
where `classes`.`id` = 1) as temp
group by temp.id;

希望它有效!