从列表中选择不在表

时间:2015-09-08 15:42:02

标签: mysql

我有一个ID列表:

(1, 2, 3, 6, 7)

还有一张桌子:

id | anothercolumn
------------------
 1 | NULL
 2 | foo
 4 | bar
 5 | NULL
 6 | NULL

我想从列表中检索不是我的表的ID的值。

预期结果:

3, 7

SELECT without FROM

我试过这样的事情:

SELECT i
WHERE i IN (1, 2, 3, 6, 7)
AND i NOT IN (SELECT id FROM mytable);

但这不是一个有效的MySQL查询(需要FROM)。

UNION

还有这种可能性:

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列表创建一个临时表:

CREATE TEMPORARY TABLE mylistofids (
    i INT
);

INSERT INTO mylistofids (i) VALUES (1), (2), (3), (6), (7);

然后在LEFT JOIN

中使用它
SELECT i
FROM mylistofids
LEFT JOIN mytable
ON mytable.id = i
WHERE mytable.id IS NULL;

这也有效,但在我的情况下,我没有权利创建一个表(临时或非临时)。

您是否看到了以最好的方式解决此问题的方法?

1 个答案:

答案 0 :(得分:6)

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

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

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;