比较两个具有不同列数的表,并返回匹配和不匹配的记录

时间:2018-07-20 17:09:06

标签: sql sql-server sql-server-2012

我必须比较两个表并使用主键Emp Id返回匹配和不匹配的记录 enter image description here

可以说,我的结果集中应该是下面这样的内容,同样我应该同时获得匹配和不匹配的记录。 如果我使用EmpId=E2,我应该得到匹配以及名称和国家/地区不匹配的值。 enter image description here 如果我使用EmpId=E4,则城市和公司不匹配。 enter image description here 有什么办法可以做到这一点吗?请帮助我。

我尝试过的方式

使用了完全连接,但没有返回我想要的内容。

Select * from Emplist A Full Join EmpInfo B on A.EmpId=B.EmpId where A.EmpId='E2'

我已经介绍了此article,但不符合我的要求。

注意:我不想提及select语句中的列,因为有时我会在两个表中都获得50多个列(很难在select语句中写入所有列名称)

2 个答案:

答案 0 :(得分:2)

您可以使用SQL Server的INTERSECT或EXCEPT。

» EXCEPT从左输入查询返回不由右输入查询输出的不同行。

» INTERSECT返回左输入查询运算符和右输入查询运算符输出的不同行。

您可以查看在线参考here

以下是您可以在SSMS中运行的示例:

创建表变量并插入数据

DECLARE @empList TABLE ( empId VARCHAR(2), [name] VARCHAR(20), city VARCHAR(20), company VARCHAR(3), country VARCHAR(4) );
DECLARE @empInfo TABLE ( empId VARCHAR(2), [name] VARCHAR(20), city VARCHAR(20), [language] VARCHAR(10), company VARCHAR(3), country VARCHAR(4) );

INSERT INTO @empList
( empId, [name], city, company, country )
VALUES
( 'E1', 'John', 'Newyork', 'CYT', 'Con1' )
, ( 'E2', 'Victor', 'London', 'KOP', 'Con2' )
, ( 'E3', 'David', 'BYJ', 'CKY', 'Con3' )
, ( 'E4', 'Neymor', 'Kiht', 'UIO', 'Con4' )
, ( 'E5', 'Justin', 'Paris', 'JHY', 'Con5' );

INSERT INTO @empInfo
( empId, [name], city, [language], company, country )
VALUES
( 'E1', 'John', 'Newyork', 'Eng', 'CYT', 'Con1' )
, ( 'E2', 'Marlya', 'London', 'French', 'KOP', 'Con9' )
, ( 'E3', 'David', 'BYJ', 'Eng', 'CKY', 'Con3' )
, ( 'E4', 'Neymor', 'LOV', 'Eng', 'UUM', 'Con4' )
, ( 'E5', 'Justin', 'Paris', 'Eng', 'JHY', 'Con5' );

相交结果:

SELECT empId, [name], city, company, country FROM @empList
INTERSECT
SELECT empId, [name], city, company, country FROM @empInfo;

+-------+--------+---------+---------+---------+
| empId |  name  |  city   | company | country |
+-------+--------+---------+---------+---------+
| E1    | John   | Newyork | CYT     | Con1    |
| E3    | David  | BYJ     | CKY     | Con3    |
| E5    | Justin | Paris   | JHY     | Con5    |
+-------+--------+---------+---------+---------+

除结果:

SELECT empId, [name], city, company, country FROM @empList
EXCEPT
SELECT empId, [name], city, company, country FROM @empInfo;

+-------+--------+--------+---------+---------+
| empId |  name  |  city  | company | country |
+-------+--------+--------+---------+---------+
| E2    | Victor | London | KOP     | Con2    |
| E4    | Neymor | Kiht   | UIO     | Con4    |
+-------+--------+--------+---------+---------+

返回单个结果集:

SELECT * FROM (

    SELECT 'matched' [state], empId, [name], city, company, country FROM @empList
    INTERSECT
    SELECT 'matched' [state], empId, [name], city, company, country FROM @empInfo

    UNION ALL

    SELECT 'mismatched' [state], empId, [name], city, company, country FROM @empList
    EXCEPT
    SELECT 'mismatched' [state], empId, [name], city, company, country FROM @empInfo

) AS singleResultset;

返回

+------------+-------+--------+---------+---------+---------+
|   state    | empId |  name  |  city   | company | country |
+------------+-------+--------+---------+---------+---------+
| matched    | E1    | John   | Newyork | CYT     | Con1    |
| matched    | E3    | David  | BYJ     | CKY     | Con3    |
| matched    | E5    | Justin | Paris   | JHY     | Con5    |
| mismatched | E2    | Victor | London  | KOP     | Con2    |
| mismatched | E4    | Neymor | Kiht    | UIO     | Con4    |
+------------+-------+--------+---------+---------+---------+

这里的警告是,列名需要匹配(它们可以被别名),这在他们的示例中大部分都需要匹配。注意,我从@empInfo SELECT中删除了“语言”列。

答案 1 :(得分:0)

这听起来像是对OUTER EXCLUDING JOIN的查询。 OUTER EXCLUDING JOIN仅返回两个表中不相等的值,但是据我所知,您不能简单地用“ OUTER EXCLUSIVE JOIN”替换短语“ INNER JOIN”

为此,将编写两个查询,一个FULL JOIN(将返回所有内容)和一个INNER JOIN(仅返回相同的列)。由此,编写一个查询,该查询将FULL JOIN合并,其中没有INNER JOIN的值。该查询的结果将仅是两个表中的行不相同的结果。

我将参考this thread和此Code Project post以获得更多详细信息。