SQL 服务器 - 相关子查询/自连接
SQL Server - Correlated Subqueries / Self Join
一个 select 声明 return 位于唯一城市和州的每个供应商的名称、城市和州(即,排除与另一个供应商具有相同城市和州的供应商)
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;
我理解第一个答案,但不理解备用查询。混淆点:return 0 行下面的行不是因为它们引用相同的 table 而没有附加的 where 子句吗?
WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID)
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;
子查询
SELECT VendorCity + VendorState
FROM Vendors AS Vendors_Sub
WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID
将 return 主查询中每一行的 vendorCity + vendorState
的所有现有组合,不包括具有相同 ID 的行。将子查询想象成为主查询中的每一行调用的函数。
如果 WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID
不存在,每个主查询行将在子查询中与自身匹配,并且整个查询将 return 没有行,因为 none 组合将是唯一的。
WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID)
不比较相同 table.
的同一行
一个相关子查询在逻辑上对外部查询中的每一行执行一次,在你的例子中它检查具有相同VendorCity
/[=13=的行]组合,但不同VendorIDs
.
事实上我更喜欢直接翻译成相关的 NOT EXISTS
:
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;
这可以防止像 'state' + 'acity'
和 'statea' + 'city'
这样的误报,它们都连接到 'stateacity'
并且适用于任何类型的数据类型。
一个 select 声明 return 位于唯一城市和州的每个供应商的名称、城市和州(即,排除与另一个供应商具有相同城市和州的供应商)
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;
我理解第一个答案,但不理解备用查询。混淆点:return 0 行下面的行不是因为它们引用相同的 table 而没有附加的 where 子句吗?
WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID)
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;
子查询
SELECT VendorCity + VendorState
FROM Vendors AS Vendors_Sub
WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID
将 return 主查询中每一行的 vendorCity + vendorState
的所有现有组合,不包括具有相同 ID 的行。将子查询想象成为主查询中的每一行调用的函数。
如果 WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID
不存在,每个主查询行将在子查询中与自身匹配,并且整个查询将 return 没有行,因为 none 组合将是唯一的。
WHERE Vendors_Sub.VendorID <> Vendors_Main.VendorID)
不比较相同 table.
一个相关子查询在逻辑上对外部查询中的每一行执行一次,在你的例子中它检查具有相同VendorCity
/[=13=的行]组合,但不同VendorIDs
.
事实上我更喜欢直接翻译成相关的 NOT EXISTS
:
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;
这可以防止像 'state' + 'acity'
和 'statea' + 'city'
这样的误报,它们都连接到 'stateacity'
并且适用于任何类型的数据类型。