mySQL - 两个表之间的区别

时间:2013-11-05 21:39:42

标签: mysql sql

我有两张表如下:

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 个答案:

答案 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_cityCITY。这将使查询执行得更快,特别是随着表的增长。

答案 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)