SQL Server-相关子查询/自联接

SQL Server-相关子查询/自联接,sql,sql-server,self-join,correlated-subquery,Sql,Sql Server,Self Join,Correlated Subquery,select语句返回位于唯一城市和州的每个供应商的名称、城市和州,即排除与另一个供应商具有相同城市和州的供应商 SELECT VendorName, VendorCity, VendorState FROM Vendors WHERE VendorState + VendorCity NOT IN (SELECT VendorState + VendorCity FROM Vendors

select语句返回位于唯一城市和州的每个供应商的名称、城市和州,即排除与另一个供应商具有相同城市和州的供应商

SELECT 
    VendorName, VendorCity, VendorState
FROM 
    Vendors
WHERE 
    VendorState + VendorCity NOT IN (SELECT VendorState + VendorCity
                                     FROM Vendors
                                     GROUP BY VendorState + VendorCity
                                     HAVING COUNT(*) > 1)
ORDER BY 
    VendorState, VendorCity;
备选答案

SELECT 
    VendorName, VendorCity, VendorState
FROM 
    Vendors AS Vendors_Main
WHERE 
    VendorCity + VendorState NOT IN (SELECT VendorCity + VendorState
                                     FROM Vendors AS Vendors_Sub
                                     WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID)
ORDER BY 
    VendorState, VendorCity;
我理解第一个答案,但不理解另一个问题。混淆点:下面的行不返回0行吗,因为它们引用的是同一个表,没有附加where子句

WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID)
子查询

SELECT  VendorCity + VendorState
FROM    Vendors AS Vendors_Sub
WHERE   Vendors_Sub.VendorID <> Vendors_Main.VendorID
将为主查询中的每一行返回所有现有的vendorCity+vendorState组合,但不包括具有相同id的组合。将子查询想象为主查询中每一行调用的函数

如果WHERE Vendors\u Sub.VendorID Vendors\u Main.VendorID不存在,则每个主查询行将与子查询中的自身匹配,整个查询将不返回任何行,因为这些组合都不是唯一的。

WHERE Vendors\u Sub.VendorID VendorID Vendors\u Main.VendorID不会比较同一表的同一行

对于外部查询中的每一行,关联子查询在逻辑上执行一次,在您的情况下,它会检查具有相同VendorCity/VendorState组合但不同VendorId的行

事实上,我更喜欢直接翻译成一个不存在的相关文件:

这可以防止诸如“state”+“acity”与“statea”+“city”之类的误报,它们都连接到“stateacity”并适用于任何类型的数据类型

SELECT  VendorCity + VendorState
FROM    Vendors AS Vendors_Sub
WHERE   Vendors_Sub.VendorID <> Vendors_Main.VendorID
SELECT VendorName, VendorCity, VendorState
FROM Vendors AS Vendors_Main
WHERE NOT EXISTS
 (
   SELECT *
   FROM Vendors AS Vendors_Sub
   WHERE Vendors_Sub.VendorCity  = Vendors_Main.VendorCity  -- same city
     AND Vendors_Sub.VendorState = Vendors_Main.VendorState -- same state
     AND Vendors_Sub.VendorID   <> Vendors_Main.VendorID    -- different vendor
 )
ORDER BY VendorState, VendorCity;