SQL SELECT使用in()但不包括其他
我有一个名为“国家”的表格,它与另一个具有多对多关系的表格“网络”相连:SQL SELECT使用in()但不包括其他,sql,cakephp,Sql,Cakephp,我有一个名为“国家”的表格,它与另一个具有多对多关系的表格“网络”相连: countries countries_networks networks +-------------+----------+ +-------------+----------+ +-------------+---------------+ | Field | Type | | Field | Type | |
countries countries_networks networks
+-------------+----------+ +-------------+----------+ +-------------+---------------+
| Field | Type | | Field | Type | | Field | Type |
+-------------+----------+ +-------------+----------+ +-------------+---------------+
| id | int(11) | | id | int(11) | | id | int(11) |
| countryName | char(35) | | country_id | int(11) | | name | varchar(100) |
+-------------+----------+ | network_id | int(11) | | description | varchar(255) |
要检索网络id为6和7的所有国家,我只需执行以下操作:(我可以进一步使用networks.name,但我知道国家网络id,所以我只需使用它们来减少SQL。)
这很好,但是我想检索网络id为8的国家,而不是其他国家
我曾经尝试过以下方法,但它仍然返回6和7英寸的网络。这和我的加入有关吗
SELECT DISTINCT countryName
FROM countries AS Country
INNER JOIN countries_networks AS n ON Country.id = n.country_id
WHERE n.network_id IN (8)
AND n.network_id not IN(6,7)
谢谢。您需要两个连接:
SELECT DISTINCT c.CountryName
FROM Countries c
INNER JOIN
countries_networks n
ON c.id = n.country_id
AND n.network_id = 8
LEFT JOIN
countries_networks n2
ON c.id = n2.country_id
AND n2.network_id IN (6, 7)
WHERE n2.country_id IS NULL
在您的查询中,最后一行检查的是8不在列表中(6,7)。如果我没看错你的问题,你想要的国家确实有ID为8的网络,但没有ID为6或7的网络。每个都需要自己的联接,并且您希望确保第二个联接没有匹配的行。您可以执行子查询:
SELECT countryName
FROM countries
WHERE country_id IN
(
SELECT country_id
FROM network
WHERE network_id = 8
)
AND country_id NOT IN
(
SELECT country_id
FROM network
WHERE network_id IN (6, 7)
)
SELECT DISTINCT c.countryName
FROM countries AS c
INNER JOIN countries_networks AS n ON c.id = n.country_id
WHERE n.network_id IN (8)
AND c.countryName NOT IN
(SELECT c2.countryName FROM countries AS c2
INNER JOIN countries_networks AS n2
WHERE n2.network_id IN (6,7))
虽然这可能不是最佳选择。之所以得到网络id为6和7的国家/地区,是因为您正在检查每个国家/地区网络记录的状况。排除6和7的条件部分根本没有效果,因为任何id为8的情况都不可能同时为6或7 您需要两次加入countries_networks表,以便可以使用一个包含国家/地区,使用一个排除国家/地区:
select countryName
from countries c
inner join countries_networks i on i.country_id = c.id and i.network_id = 8
left join countries_networks e on e.country_id = c.id and e.network_id in (6,7)
where e.id is null
此外,您不需要区分此查询,除非您在同一个国家/地区和网络id之间实际有多个连接。使用NOT EXISTS谓词的另一个解决方案
SELECT DISTINCT countryName
FROM countries AS Country
INNER JOIN countries_networks AS n ON Country.id = n.country_id
WHERE n.network_id IN (8)
AND NOT EXISTS (SELECT 1 FROM countries_networks n1
WHERE n1.country_id = Country.id AND n1.network_id !=8)
虽然您正在抵制
网络
表上的附加连接,但这确实是最简单的方法。如果根据该表测试id,则应适当限制结果:
SELECT countryName
FROM countries AS Country JOIN countries_networks AS cn
ON Country.id = cn.country_id
JOIN networks n
ON cn.network_id = n.id
WHERE n.network_id IN (8)
针对
网络
表的测试应限制结果,而不考虑国家/地区网络
表中可能链接的任何内容。它的性能(和可读性)也应该比子查询或我能想到的任何其他解决方案更好。。。。这是我5或6分钟前写的。
SELECT countryName
FROM countries AS Country JOIN countries_networks AS cn
ON Country.id = cn.country_id
JOIN networks n
ON cn.network_id = n.id
WHERE n.network_id IN (8)