我使用以下查询:
select * from A LEFT JOIN B on ( A.t_id != B.t_id)
获取A中不在B中的所有记录。
除非表B完全为空,否则结果很好,但是即使从表A中我也没有得到任何记录。
它无法使用!
CREATE TABLE IF NOT EXISTS `T1` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`t_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3;
T1
INSERT INTO `T1` (`id`, `title`, `t_id`) VALUES
(1, 'apple', 1),
(2, 'orange', 2);
T2
CREATE TABLE IF NOT EXISTS `T2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`t_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2;
T2
INSERT INTO `T2` (`id`, `title`, `t_id`) VALUES
(1, 'dad', 2);
现在我想获取T1中没有相应记录的所有记录。
我试试
SELECT *
FROM T1
LEFT OUTER JOIN T2 ON T1.t_id != T2.t_id
它不起作用。
答案 0 :(得分:3)
select * from A where t_id not in (select t_id from B)
答案 1 :(得分:3)
你有两个问题
1)诊断错误
给出两个表
mysql> CREATE TABLE T1 (ID INT);
Query OK, 0 rows affected (0.10 sec)
mysql> CREATE TABLE T2 (ID INT);
Query OK, 0 rows affected (0.10 sec)
mysql> INSERT INTO T1 VALUES (1);
Query OK, 1 row affected (0.00 sec)
查询
mysql> SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.ID != T2.ID;
+------+------+
| ID | ID |
+------+------+
| 1 | NULL |
+------+------+
1 row in set (0.00 sec)
返回不匹配的行,即使T2为空(所以你的问题实际上在别处;你可能在这里为我们简化了查询)。
2)查询效果
有几种方法可以编写一个查询,从表A中获取记录而不是表B.
但是,它们并非都是等价的,例如mysql为
创建了不同的计划mysql> EXPLAIN SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.ID != T2.ID;
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
| 1 | SIMPLE | T1 | system | NULL | NULL | NULL | NULL | 1 | |
| 1 | SIMPLE | T2 | system | NULL | NULL | NULL | NULL | 0 | const row not found |
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
2 rows in set (0.00 sec)
mysql> EXPLAIN SELECT * FROM T1 WHERE ID NOT IN (SELECT ID FROM T2);
+----+--------------------+-------+--------+---------------+------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+--------+---------------+------+---------+------+------+--------------------------------+
| 1 | PRIMARY | T1 | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DEPENDENT SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | no matching row in const table |
+----+--------------------+-------+--------+---------------+------+---------+------+------+--------------------------------+
2 rows in set (0.02 sec)
mysql> EXPLAIN SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.ID = T2.ID WHERE T2.ID IS NULL;
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
| 1 | SIMPLE | T1 | system | NULL | NULL | NULL | NULL | 1 | |
| 1 | SIMPLE | T2 | system | NULL | NULL | NULL | NULL | 0 | const row not found |
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
2 rows in set (0.00 sec)
mysql> EXPLAIN SELECT * FROM T1 WHERE NOT EXISTS (SELECT ID FROM T2 WHERE T2.ID = T1.ID);
+----+--------------------+-------+--------+---------------+------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+--------+---------------+------+---------+------+------+--------------------------------+
| 1 | PRIMARY | T1 | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DEPENDENT SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | no matching row in const table |
+----+--------------------+-------+--------+---------------+------+---------+------+------+--------------------------------+
2 rows in set (0.00 sec)
因此,对于同一查询的4个不同版本(如果我没有犯下愚蠢的错误,它们应该都是等价的),你会得到两个不同的执行计划。
判断此示例中的计划应该不,因为表T1和T2分别只包含一行和零行,而计划执行取决于大小,索引和统计。对于生产系统,我会比较计划,因为我认为mysql不会认识到这些查询是否相等。
修改强> Ups,我确实对你的查询的解释发出了一个愚蠢的错误......
SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.t_id != T2.t_id
事实 1)左连接
SELECT * FROM T1 LEFT OUTER JOIN T2 ...
如果没有其他WHERE条件(无论连接条件如何!),将从T1获取所有记录而不管连接标准。
2)连接条件确定哪些记录将从T1加入记录(确定基数和T2中属性的值)
所以对于来自T1的特定记录,它将
2a)仅当且仅当连接条件T1.t_id != T2.t_id
FALSE 全部来自T2的记录时,才使用NULLS填充来自T2的属性。仅当T1中的特定记录中T2中的每个记录与T1中的记录具有相同的t_id
值时,才会发生这种情况。
2b)如果连接条件为TRUE,它将从T2返回所有记录,而这一切肯定不是你想要的
以下是继续使用示例数据的示例
mysql> INSERT INTO `T2` (`id`, `title`, `t_id`) VALUES (8, 'xdad', 3);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.ID != T2.ID;
+----+--------+------+------+-------+------+
| id | title | t_id | id | title | t_id |
+----+--------+------+------+-------+------+
| 1 | apple | 1 | 8 | xdad | 3 |
| 2 | orange | 2 | 1 | dad | 2 |
| 2 | orange | 2 | 8 | xdad | 3 |
+----+--------+------+------+-------+------+
3 rows in set (0.00 sec)
其他三个版本确实应该是等价的
SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.t_id = T2.t_id WHERE T2.t_id IS NULL;
SELECT * FROM T1 WHERE NOT EXISTS (SELECT t_id FROM T2 WHERE T2.t_id = T1.t_id);
SELECT * FROM T1 WHERE t_id NOT IN (SELECT t_id FROM T2);
最后一个版本也可以写成
SELECT * FROM T1 WHERE t_id NOT IN (SELECT t_id FROM T2 WHERE T2.t_id = T1.t_id);
对不起,我第一次尝试去集中注意力..
答案 2 :(得分:0)
尝试
SELECT * 从A LEFT OUTER JOIN B ON(A.t_id!= B.t_id)