MySQL变量格式,用于“ NOT IN”值列表


74

疯狂尝试在类型查询中设置变量:

SET @idcamposexcluidos='817,803,495';

这样我就可以在

WHERE id_campo not in (@idcamposexcluidos)

我尝试过用不同的格式定义变量,但没有运气,似乎也找不到上述的特定示例:

SET @idcamposexcluidos='(817,803,495)';
...
WHERE id_campo not in @idcamposexcluidos


SET @idcamposexcluidos=817,803,495;

没有成功。它要么返回错误,要么忽略值。


2
你不能那样使用in。您需要单独的变量或使用动态SQL。
juergen d 2012年

FIND_IN_SET并且LIKE适合小桌子。但是它们表现不佳,因为它们必须查看每一行。大多数语言没有简单的方法(如果有的话)来构造IN(...)可以使用索引的快得多的子句。
瑞克·詹姆斯

Answers:


124

您不能使用这样的IN子句。它在您的子句中编译为单个字符串IN。但是IN子句需要单独的值。

WHERE id_campo not in (@idcamposexcluidos)

编译为

WHERE id_campo not in ('817,803,495')

但这应该是

WHERE id_campo not in ('817','803','495')

为了克服这个问题,可以使用动态SQL或在MySQL中使用FIND_IN_SET

SET @idcamposexcluidos='817,803,495';
...
WHERE FIND_IN_SET(id_campo, @idcamposexcluidos) = 0

但是使用像这样的函数FIND_IN_SET()不能使用索引。


太棒了!起初我以为这是行不通的,因为我既忽略又不熟悉FIND_IN_SET方法。我担心由于“ 803”,“ 80”会产生误报,但效果很好!
donL

6
而且,如果您想使用IN子句而不是NOT IN,只需将'= 0'替换为'> 0'-> WHERE FIND_IN_SET(id_campo,@idcamposexcluidos)> 0
Bruno

3
@Bruno您也可以这样做:WHERE FIND_IN_SET(id_campo, @idcamposexcluidos)。也就是说,将结果视为FIND_IN_SET布尔值。NOT IN等价表达式的答案也可以这样写:WHERE NOT FIND_IN_SET(id_campo, @idcamposexcluidos)
Kip

2
关于此的重要说明:数据库引擎似乎不够聪明,无法优化查询。EXPLAIN EXTENDED SELECT * FROM users WHERE FIND_IN_SET(user_id, @userlist) ==>全表扫描(在大表上非常慢)。EXPLAIN EXTENDED SELECT * FROM users WHERE user_id IN (1, 2, 3, 4)==>使用主键索引(非常快)。(已在MySQL 5.6 / innodb上测试。)
Kip

1
@Kip:使用函数通常会阻止使用索引。
juergen d

4

如果使用mysql> 5.1,则可以使用:

CREATE TYPE lista as (
    clave int4,
    valor int4
);

CREATE OR REPLACE FUNCTION test(IN vArray lista[])
...

   WHERE FIND_IN_SET(id_campo, vArray)
...

在其他情况下,您可以使用技巧:

WHERE id_campo IN ( SELECT 817 as valor UNION ALL 
                SELECT 803 as valor UNION ALL
                    SELECT 495 as valor)

2

通过使用CONCAT(),管道分隔符(而不是逗号)和一些“反向逻辑”,您可以在NOT IN列表中使用变量,但可以使用-代替NOT LIKE

例:

SET @idcamposexcluidos = '|817|803|495|';

SELECT
    *
FROM
    your_table
WHERE
    @idcamposexcluidos NOT LIKE CONCAT('%|', id_campo, '|%');

这对字符串和数字列均适用。


似乎也可以,但是不确定为什么我在同一搜索中得到更多的行!任何案例案例解决方案都非常有效。谢谢
luison 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.