SQL - How to Return rows from left table not found in right table?
我有两个列名相似的表,需要从左表返回右表中找不到的记录?我有一个主键(列),它将帮助我比较两个表。首选哪种连接?
试试这个
1 2 3 | SELECT f.* FROM first_table f LEFT JOIN second_table s ON f.key=s.key WHERE s.key IS NULL |
有关详细信息,请阅读本文:加入SQL Server
如果您需要T-SQL,那么让我们先看看基本原理。这里有三种类型的联接,每种联接都有自己的一组逻辑处理阶段,如下所示:
接下来是第三种连接,
在
现在,我们来看一个问题:要从左表返回在右表中找不到的记录,请使用
我也喜欢用不存在。在性能方面,如果索引正确,它应该与左联接执行相同或更好。而且更容易阅读。
1 2 3 4 5 6 | SELECT Column1 FROM TableA a WHERE NOT EXISTS ( SELECT Column1 FROM Tableb b WHERE a.Column1 = b.Column1 ) |
我只能在另外两个答案中添加一个代码示例:但是,我发现看到它的实际效果是很有用的(在我看来,其他答案更好,因为它们解释了它)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | DECLARE @testLeft TABLE (ID INT, SomeValue VARCHAR(1)) DECLARE @testRight TABLE (ID INT, SomeOtherValue VARCHAR(1)) INSERT INTO @testLeft (ID, SomeValue) VALUES (1, 'A') INSERT INTO @testLeft (ID, SomeValue) VALUES (2, 'B') INSERT INTO @testLeft (ID, SomeValue) VALUES (3, 'C') INSERT INTO @testRight (ID, SomeOtherValue) VALUES (1, 'X') INSERT INTO @testRight (ID, SomeOtherValue) VALUES (3, 'Z') SELECT l.* FROM @testLeft l LEFT JOIN @testRight r ON l.ID = r.ID WHERE r.ID IS NULL |
这个页面给出了不同连接类型的详细分解,以及维恩图可视化以帮助…好。。。可视化连接中的差异。
正如注释所说,这是一个非常基本的查询,从它的发音来看,所以您应该尝试理解连接和它们实际含义之间的区别。
查看http://blog.codingsurror.com/a-visual-explation-of-sql-joins/
您正在查找一个查询,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | DECLARE @table1 TABLE (test INT) DECLARE @table2 TABLE (test INT) INSERT INTO @table1 ( test ) SELECT 1 UNION ALL SELECT 2 INSERT INTO @table2 ( test ) SELECT 1 UNION ALL SELECT 3 -- Here's the important part SELECT a.* FROM @table1 a LEFT JOIN @table2 b ON a.test = b.test -- this will return all rows from a WHERE b.test IS NULL -- this then excludes that which exist in both a and b -- Returned results: 2 |
从左表中选择*键字段不在其中(从右表中选择键字段)
这是现实工作中的一个例子,我被要求提供过去6个月内从我们网站上购买的用户列表,但在过去3个月内没有。
对我来说,我能想到的最容易理解的方式是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | --Users that bought from us 6 months ago and between 3 months ago. DECLARE @6To3MonthsUsers TABLE (UserID INT,OrderDate datetime) INSERT @6To3MonthsUsers SELECT u.ID,opd.OrderDate FROM OrdersPaid opd INNER JOIN Orders o ON opd.OrderID = o.ID INNER JOIN Users u ON o.BuyerID = u.ID WHERE 1=1 AND opd.OrderDate BETWEEN DATEADD(m,-6,GETDATE()) AND DATEADD(m,-3,GETDATE()) --Users that bought from us in the last 3 months DECLARE @Last3MonthsUsers TABLE (UserID INT,OrderDate datetime) INSERT @Last3MonthsUsers SELECT u.ID,opd.OrderDate FROM OrdersPaid opd INNER JOIN Orders o ON opd.OrderID = o.ID INNER JOIN Users u ON o.BuyerID = u.ID WHERE 1=1 AND opd.OrderDate BETWEEN DATEADD(m,-3,GETDATE()) AND GETDATE() |
现在,有了这两张表,我只需要从@6to3monthsusers表中获取不在@last3monthsusers表中的用户。
实现这一点有两种简单的方法:
使用左联接:
1 2 3 4 5 | SELECT DISTINCT a.UserID FROM @6To3MonthsUsers a LEFT JOIN @Last3MonthsUsers b ON a.UserID = b.UserID WHERE b.UserID IS NULL |
不在:
1 2 3 | SELECT DISTINCT a.UserID FROM @6To3MonthsUsers a WHERE a.UserID NOT IN (SELECT b.UserID FROM @Last3MonthsUsers b) |
两种方法都会得到相同的结果,我个人更喜欢第二种方法,因为它更具可读性。