1

我有两个表如下:

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');
4

4 回答 4

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

于 2013-11-06T01:18:58.727 回答
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. 这将使查询的执行速度显着加快,尤其是随着表的增长。

于 2013-11-06T01:01:31.163 回答
0

也许你需要的是:

SELECT cty.`idCITY_NAME`
FROM `keywords_by_city` kbc
LEFT JOIN `city` cty ON cty.`idCITY_NAME` = kbc.`CITY`
WHERE kbc.`idKEYWORD` <> 781 
于 2013-11-05T21:47:47.297 回答
-1
SELECT idCITY_NAME
FROM city
WHERE idCITY_NAME NOT IN (SELECT CITY FROM keywords_by_city WHERE idKEYWORD != 781)
于 2013-11-06T00:48:33.457 回答