三个表的联合(无任何重复项)在Mysql中减去一个表

时间:2019-07-09 15:56:39

标签: mysql join union

表格:2018

No  Email

1   Lilly@gmail.com

2   brens@gmail.com

3   susan@gmail.com

4   resh@gmail.com

表格:2017

No   Email

1    chitta@gmail.com

2    resh@gmail.com

3    brens@gmail.com

4    minu@gmail.com

表格:2016

No   Email

1     brens@gmail.com

2     chitta@gmail.com

3     lisa@gmail.com

4     monay@gmail.com

5     many@gmail.com

表格:2019

No   Email

1    brens@gmail.com

2    chitta@gmail.com

3    rinu@gmail.com

4    emma@gmail.com

我需要执行表2018、2017、2016的联合,没有重复的电子邮件减去表2019,结果应类似于

结果

No  Email

1    Lilly@gmail.com

2    susan@gmail.com

3    resh@gmail.com

4    minu@gmail.com

5   lisa@gmail.com

6   monay@gmail.com

7   many@gmail.com

减号操作在Mysql中不可用。

select a.*from(select *from y2018 union select *from y2017 where not exists(select *from y2018 where y2018.email=y2017.email ) union select *from y2016 where not exists(select *from y2018 where y2018.email=y2016.email ))a LEFT OUTER JOIN y2019 b on a.email=b.email  where b.email is null ;

这给出了结果,但并没有消除(2017年联合2016年)中的重复项

有人请帮助我

2 个答案:

答案 0 :(得分:0)

  

我需要执行表2018、2017、2016的联合,没有任何重复   电子邮件减去表格2019

最容易模拟/仿真减号/期望值的方法是使用NOT IN()

查询

SELECT 
   (@ROW_NUMBER := @ROW_NUMBER + 1) AS 'No' 
 , unique_email.Email
FROM (

  SELECT 
    DISTINCT 
      years_merged.Email  
  FROM (

    SELECT 
     Email
    FROM 
     y2019
    UNION ALL
    SELECT 
     Email
    FROM 
     y2018
    UNION ALL
    SELECT 
     Email
    FROM
     y2017   
    UNION ALL
    SELECT 
     Email
    FROM 
     y2016     

  ) AS years_merged
  WHERE 
   years_merged.Email NOT IN(SELECT y2019.Email FROM y2019 ) 
  ORDER BY
   years_merged.Email ASC
) AS unique_email
CROSS JOIN (SELECT @ROW_NUMBER := 0) AS init
ORDER BY 
  @ROW_NUMBER ASC

结果

| No  | Email           |
| --- | --------------- |
| 1   | Lilly@gmail.com |
| 2   | lisa@gmail.com  |
| 3   | many@gmail.com  |
| 4   | minu@gmail.com  |
| 5   | monay@gmail.com |
| 6   | resh@gmail.com  |
| 7   | susan@gmail.com |

是的,顺序是不同的,但这是您可以做的最好的事情,因为SQL标准将SQL表定义为无序排序。

请参阅demo

但是,与... LEFT JOIN ... ON ... WHERE .. IS NULL相比,使用NOT IN()进行仿真/模拟减去/期望可能会更好。

请参见demo

答案 1 :(得分:0)

我找到了一个更好的方法,创建一个视图并在其中保存查询的一部分。它还有助于减少处理时间。

create view vm as select *from y2018 union select *from y2017 where not exists(select *from y2018 where y2018.email=y2017.email);

SELECT  a.*FROM(SELECT * FROM vm union select *from y2016 where not exists(select *from vm where vm.email=y2016.email))a LEFT JOIN y2019 b ON a.email=b.email where b.email is null;

“ vm”是视图