我必须比较两个表并使用主键Emp Id返回匹配和不匹配的记录
可以说,我的结果集中应该是下面这样的内容,同样我应该同时获得匹配和不匹配的记录。
如果我使用EmpId=E2
,我应该得到匹配以及名称和国家/地区不匹配的值。
如果我使用EmpId=E4
,则城市和公司不匹配。
有什么办法可以做到这一点吗?请帮助我。
我尝试过的方式
使用了完全连接,但没有返回我想要的内容。
Select * from Emplist A Full Join EmpInfo B on A.EmpId=B.EmpId where A.EmpId='E2'
我已经介绍了此article,但不符合我的要求。
注意:我不想提及select语句中的列,因为有时我会在两个表中都获得50多个列(很难在select语句中写入所有列名称)
答案 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以获得更多详细信息。