40

询问:

select id from users where id in (1,2,3,4,5)

如果用户表包含 ids 1、2、3,这将返回 1、2 和 3。我想要一个返回 4 和 5 的查询。换句话说,我不希望查询返回任何存在的行在表格中,我想给它一个数字列表并从该列表中获取出现在表格中的值。

(更新以澄清几个不适用的答案后的问题)

4

6 回答 6

21

如果您不想(明确)使用临时表,这将起作用:

SELECT id FROM (
  (SELECT 1 AS id) UNION ALL
  (SELECT 2 AS id) UNION ALL
  (SELECT 3 AS id) UNION ALL
  (SELECT 4 AS id) UNION ALL
  (SELECT 5 AS id)
) AS list
LEFT JOIN users USING (id)
WHERE users.id IS NULL

但是,它很丑,很长,如果 ID 列表很长,我怀疑它会如何执行。

于 2014-11-21T03:26:59.270 回答
16

给定数字是一个固定的列表。我能想到的最快方法是有一个测试表,填充这些数字并执行

未经测试的选择语句 - 但您将遵循原则。

select test.number 
from test 
left join 
    users 
on 
    test.number = users.id 
where test.number <> users.id

然后,您将取回所有没有匹配 user.id 的号码,因此可以填补漏洞..

于 2012-04-04T14:50:29.233 回答
16

有同样的需求,并建立在 BugFinder 使用会话中的临时表的答案之上。这样它会在我完成查询后自动销毁,所以我不必处理房屋清洁,因为我会经常运行这种类型的查询。

创建临时表:

CREATE TEMPORARY TABLE tmp_table (id INT UNSIGNED);

使用您将检查的值填充 tmp_table:

INSERT INTO tmp_table (id) values (1),(2),(3),(4),(5);

创建并填充表后,像使用任何常规表一样运行查询:

SELECT tmp_table.id
  FROM tmp_table
  LEFT JOIN users u
  ON tmp_table.id = u.id
  WHERE u.id IS NULL;

MySQL 临时表上的这个信息也很有用

于 2013-04-19T16:22:41.397 回答
3

另一种选择是使用另一个包含所有可能 id 的表,然后从那里进行选择:

mysql> describe ids;
+-------+-----------------+------+-----+---------+-------+
| Field | Type            | Null | Key | Default | Extra |
+-------+-----------------+------+-----+---------+-------+
| id    | int(5) unsigned | NO   |     | 0       |       |
+-------+-----------------+------+-----+---------+-------+
1 row in set (0.05 sec)

mysql> select * from ids;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
+----+
5 rows in set (0.00 sec)

mysql> select * from users;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+
3 rows in set (0.00 sec)


mysql> select id from ids where id not in (select id from users);
+----+
| id |
+----+
|  4 |
|  5 |
+----+
2 rows in set (0.04 sec)

添加的副作用 - 允许您通过插入 ids 表来扩展结果列表

于 2012-04-04T15:00:34.653 回答
2
select missing.id
  from
(select ELT(@indx, 1,2,3,4,5) as id, @indx:=@indx+1
  from (select @indx:=1) init,
    users
  where ELT(@indx, 1,2,3,4,5) is not null
) missing
  left join users u using(id)
where u.id is null;

你在这里拥有的是:

  • ELT与变量一起,@indx您可以将列表“转置”为一列。
  • (select @indx:=1)需要将 indx 初始化为 1
  • 并且users需要内部选择中的表,以便 MySQL 可以进行迭代(因此列表的大小不能超过 users 表中的行数,如果是这种情况,您可以使用任何其他足够大的表来代替对于内部用户来说,表本身并不重要,只是有一些东西可以迭代,所以只有它的大小才重要)。
  • ELT(@indx, 1,2,3,4,5) is not null嵌套选择中的条件是在索引超出列表大小时停止迭代。

其余的很简单 -left join并检查null.

于 2018-05-31T01:25:18.850 回答
-2

抱歉,我无法添加评论,@Austin,

你有我的+1。

无论如何,不​​确定这是否适用于 mysql,但是更改所有原子选择连接联合的值集,所以你有类似的东西:

SELECT id FROM (
    VALUES (1), (2), (3), (4), (5)
) AS list(id)
LEFT JOIN users USING (id)
WHERE users.id IS NULL
于 2015-12-18T08:59:27.680 回答