MySQL中的空IN子句参数列表

Wiz*_*Wiz 60 mysql sql in-clause

当您执行IN子句为空的SQL查询时会发生什么?

例如:

SELECT user WHERE id IN ();
Run Code Online (Sandbox Code Playgroud)

MySQL是否会按预期处理(即始终为false),如果没有,我的应用程序在IN动态构建子句时如何处理这种情况?

Bar*_*mar 50

如果我有一个应用程序,我正在IN动态构建列表,并且它可能最终为空,我有时会做的是用不可能的值初始化列表并添加到那里.例如,如果它是一个用户名列表,我将从一个空字符串开始,因为那不是一个可能的用户名.如果它是auto_increment ID,我将使用-1,因为实际值总是正数.

如果由于没有不可能的值而不可行,则必须使用条件来决定是否AND column IN ($values)WHERE子句中包含表达式.

  • 有人给我们一些 SQL 推理吗?正如OP所说,直觉行为总是评估为错误。 (2认同)
  • 这只是一个语法问题——他们不想允许空列表。 (2认同)

Asa*_*din 13

您的查询与有效语法的最接近的近似值是:

SELECT user FROM tbl1 WHERE id IN (SELECT id FROM tbl1 WHERE FALSE);
Run Code Online (Sandbox Code Playgroud)

这将无条件地返回一个空结果集.括号中的子查询总是返回一个空集,正如我前面提到的,在空集中找不到任何值,因为空集不包含任何值.

  • 在动态生成文字"IN"列表的情况下,这实际上没有用.他不是在寻找一种方法来产生一个空洞的"IN"子句,他想知道如果在意外发生时如何处理它,因为他给出了一个空数组的值. (6认同)
  • 另一个返回空集的子查询是`(select top 0 0)`,它具有不需要表名的优点. (3认同)
  • 该问题指定 MySQL 并且“SELECT TOP N”不是 MySQL。另一方面,“(SELECT 0 WHERE 0)”有效。然而,在 MySQL 5.7 中执行“IN (SELECT ...)”似乎会创建一个“依赖子查询”(如“解释”中所示),并且生成的查询非常慢。 (3认同)
  • 或只是“从tbl1 WHERE ID IN(FALSE)中选择用户” (2认同)
  • @NicolaPedretti假设`id`不是布尔字段,这可能是一个合理的假设,但仍然是一个假设. (2认同)

Pav*_*nik 11

这给了我0结果:

SELECT id FROM User
WHERE id IN (NULL);
Run Code Online (Sandbox Code Playgroud)

试用MYSQL 5.6

  • 这可能有问题,因为`id IN(NULL)`计算为"NULL"而不是"FALSE".这主要是"NOT IN"的一个问题:`SELECT id FROM User WHERE id NOT IN(NULL);`也将返回0结果. (10认同)

Jus*_*s12 7

使用总是错误的陈述

在创建 SQL 之前,请检查数组大小。如果大小为 0,则生成 where 语句 as 1 = 2,如下所示:

SELECT * FROM USERS WHERE name in () 
Run Code Online (Sandbox Code Playgroud)

变成

SELECT * FROM USERS WHERE 1 = 2 
Run Code Online (Sandbox Code Playgroud)

对于空数组上的“not in”,生成一个始终为真的语句,如下所示:

SELECT * FROM USERS WHERE name not in () 
Run Code Online (Sandbox Code Playgroud)

变成

SELECT * FROM USERS WHERE 1 = 1
Run Code Online (Sandbox Code Playgroud)

这应该适用于更复杂的查询:

SELECT * FROM USERS WHERE (name in () OR name = 'Alice') 
Run Code Online (Sandbox Code Playgroud)

变成

SELECT * FROM USERS WHERE (1 = 2 OR name = 'Alice') 
Run Code Online (Sandbox Code Playgroud)

  • 好吧,在这种情况下我实际上可以只是“WHERE true”和“WHERE false”,或者我错过了什么。然而,在动态构建查询时,这两种方法都不是理想的。 (2认同)

Man*_*ion 5

如果将AUTO_INCREMENT用作ID(1,2,3,..),并且数组为空,则可以添加一项[0]。所以会的

if (empty($arr)) {
   $arr[] = 0;
}

SELECT user WHERE id IN (0);
Run Code Online (Sandbox Code Playgroud)

而且不会有mysql parse错误。这种情况在子查询中非常有用-当您的主查询不依赖于子查询结果时。


更好的方法-如果数组为空,请不要调用查询。

$data = null;
if (!empty($arr)) {
    $data = ... call query
}
Run Code Online (Sandbox Code Playgroud)


Дав*_*ико 5

NULL例如,您不能将 IN 运算符留空,您必须在其中放入一些内容。但即使在这种情况下,它也不会按预期工作,因为与NULL总是返回NULL(空)。一种可能的解决方案是添加子选择。

例子:

SELECT user_id FROM users;

+-----------+
| user_id   |
+-----------+
|      1000 |
|      1001 |
|      1002 |
|      1003 |
|      1004 |
|      1005 |
|      1006 |
|      1007 |
|      1008 |
|      1009 |
|      1010 |
+-----------+

SELECT user_id FROM users WHERE user_id NOT IN ();
ERROR: 1064: You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax to use near ')' at line 1

SELECT user_id FROM users WHERE user_id NOT IN (NULL);
Empty set (0.0003 sec)    

SELECT user_id FROM users WHERE user_id IN (1001, 1002, 1003) 
AND user_id NOT IN (SELECT user_id FROM users WHERE user_id IN (NULL));
+---------+
| user_id |
+---------+
|    1001 |
|    1002 |
|    1003 |
+---------+
3 rows in set (0.0004 sec)
Run Code Online (Sandbox Code Playgroud)

您稍微修改(缩短)查询,但我认为它们也会慢一些。