我有两张表如下:
CREATE TABLE `keywords_by_city` (
`idKEYWORD` int(11) NOT NULL,
`CITY` varchar(45) NOT NULL);
CREATE TABLE `city` (
`idCITY_NAME` varchar(50) NOT NULL DEFAULT ''
);
我想获得idKeyword = 781不存在的所有城市的列表。
我尝试按如下方式创建查询,但我认为不正确:
SELECT cty.`idCITY_NAME`
FROM `keywords_by_city` kbc
LEFT JOIN `city` cty ON cty.`idCITY_NAME` = kbc.`CITY`
WHERE kbc.`idKEYWORD` IS NULL
AND kbc.`idKEYWORD` = 781
我也尝试了以下内容:
SELECT `CITY`
FROM `keywords_by_city` kbc
WHERE kbc.`idKEYWORD` = 781
AND kbc.`CITY` NOT IN (SELECT `idCITY_NAME` FROM `city`);
这些似乎都不起作用。有人可以请帮助。如果可能的话,我更喜欢没有子查询的解决方案。
更新
我正在使用以下数据:
INSERT INTO keywords_by_city (idKEYWORD, CITY)
VALUES (781, 'NYC'), (266855, 'NYC'),
(266856, 'NYC'), (266857, 'NYC'),
(266858, 'NYC'), (266859, 'NYC');
INSERT INTO `city`
(`idCITY_NAME`)
VALUES
('NYC'),('Jersey City'),
('San Jose'),('Albany');
答案 0 :(得分:1)
你的尝试很接近。您只需要交换表并将关键字ID要求放入join子句:
SELECT cty.`idCITY_NAME`
FROM `city` cty
LEFT JOIN `keywords_by_city` kbc ON cty.`idCITY_NAME` = kbc.`CITY` AND kbc.`idKEYWORD` = 781
WHERE kbc.`idKEYWORD` IS NULL
此外,标准做法是在外键字段上添加索引 - 即。 keywords_by_city
。CITY
。这将使查询执行得更快,特别是随着表的增长。
答案 1 :(得分:1)
t1 LEFT JOIN t2
表示t1表是外部的,t2表是NESTED LOOP JOIN
类似的东西:
foreach (row in t1) {
if ((t1.col1 matches t2.col1) OR (t1.col1 doest not match t2.col2)) {
JOIN condition match.
}
}
所以,你的查询改变如下:
SELECT cty.`idCITY_NAME`
FROM `city` cty
LEFT JOIN `keywords_by_city` kbc
ON cty.`idCITY_NAME` = kbc.`CITY` AND kbc.`idKEYWORD` = 781
WHERE kbc.`CITY` IS NULL
如果您使用INNER JOIN
,优化程序会使用成本函数选择外部表。但是LEFT JOIN
左边的桌子位于NESTED LOOP JOIN
的外边,右边的桌子位于RIGHT JOIN
答案 2 :(得分:0)
也许你需要的是:
SELECT cty.`idCITY_NAME`
FROM `keywords_by_city` kbc
LEFT JOIN `city` cty ON cty.`idCITY_NAME` = kbc.`CITY`
WHERE kbc.`idKEYWORD` <> 781
答案 3 :(得分:-1)
SELECT idCITY_NAME
FROM city
WHERE idCITY_NAME NOT IN (SELECT CITY FROM keywords_by_city WHERE idKEYWORD != 781)