Mysql 从列表中选择不在表中的值

Mysql 从列表中选择不在表中的值,mysql,Mysql,我有一个ID列表: (1, 2, 3, 6, 7) CREATE TEMPORARY TABLE mylistofids ( i INT ); INSERT INTO mylistofids (i) VALUES (1), (2), (3), (6), (7); 和一张桌子: id | anothercolumn ------------------ 1 | NULL 2 | foo 4 | bar 5 | NULL 6 | NULL 我想从列表中检索不是表ID的值 预

我有一个ID列表:

(1, 2, 3, 6, 7)
CREATE TEMPORARY TABLE mylistofids (
    i INT
);

INSERT INTO mylistofids (i) VALUES (1), (2), (3), (6), (7);
和一张桌子:

id | anothercolumn
------------------
 1 | NULL
 2 | foo
 4 | bar
 5 | NULL
 6 | NULL
我想从列表中检索不是表ID的值

预期结果:

3, 7
不从中选择 我试过这样的方法:

SELECT i
WHERE i IN (1, 2, 3, 6, 7)
AND i NOT IN (SELECT id FROM mytable);
但这不是有效的MySQL查询(需要来自的

联合 还有这种可能性:

SELECT i
FROM (
    SELECT 1 AS i
    UNION SELECT 2
    UNION SELECT 3
    UNION SELECT 6
    UNION SELECT 7 ) AS mylistofids
LEFT JOIN mytable
ON mytable.id = i
WHERE mytable.id IS NULL;
这是可行的,但如果我的ID列表变大,查询很快就会变得巨大

临时桌 我还可以为我的ID列表创建一个临时表:

(1, 2, 3, 6, 7)
CREATE TEMPORARY TABLE mylistofids (
    i INT
);

INSERT INTO mylistofids (i) VALUES (1), (2), (3), (6), (7);
然后在
左连接中使用它

SELECT i
FROM mylistofids
LEFT JOIN mytable
ON mytable.id = i
WHERE mytable.id IS NULL;
这也可以,但在我的情况下,我没有创建表的权限(临时或非临时)


你有没有找到一种最好的方法来解决这个问题?

临时表是最好的解决方案,但如果不可能,你可以通过选择常数并将它们合并在一起来伪造临时表

使用此解决方案,您可以执行以下操作:-

SELECT i
FROM 
(
    SELECT 1 AS i UNION SELECT 2 UNION SELECT 3 UNION SELECT 6 UNION SELECT 7
) AS mylistofids 
LEFT JOIN mytable
ON mytable.id = i
WHERE mytable.id IS NULL;
您还可以通过交叉连接数字范围来生成大量数字范围(假设您正在处理整数ID)。然后只需选择in子句中的选项:-

SELECT i
FROM 
(
    SELECT units.i + tens.i * 10 + hundreds.i * 100 + thousands.i * 1000 + tensthousands.i * 10000 AS i
    FROM (SELECT 1 AS i UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0 ) AS units
    CROSS JOIN (SELECT 1 AS i UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0 ) AS tens
    CROSS JOIN (SELECT 1 AS i UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0 ) AS hundreds
    CROSS JOIN (SELECT 1 AS i UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0 ) AS thousands
    CROSS JOIN (SELECT 1 AS i UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0 ) AS tensthousands
) AS mylistofids 
LEFT JOIN mytable
ON mytable.id = i
WHERE mylistofids.i IN (1, 2, 3, 6, 7)
AND mytable.id IS NULL;

如果没有临时表,您可能必须在调用代码中解决它。一旦列表变大,DBMS将达到IN语句的限制。此外,IN语句不会向结果中添加新键,因此不带FROM的SELECT(即使有FROM)将始终失败。联合版本可以工作,但对于较大的数字来说速度较慢。第一位没有区别,但您可以扩展它以使用第二个解决方案。我怀疑性能会很糟糕,但在大列表的情况下这是个好主意(而不是一个接一个地联合列表中的每个项目)!明天我将尝试对这个解决方案进行基准测试。我怀疑你是对的,但是如果你厚颜无耻,并且有一个包含连续id字段序列的现有表,你可以使用它!