Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何对SQL中包含多个值的数据库列执行WHERE NOT IN_Php_Mysql_Sql - Fatal编程技术网

Php 如何对SQL中包含多个值的数据库列执行WHERE NOT IN

Php 如何对SQL中包含多个值的数据库列执行WHERE NOT IN,php,mysql,sql,Php,Mysql,Sql,当数据库列和检查条件中有多个值时,如何执行WHERE NOT IN条件 如果用户不属于excludedUserGroup,我想将其状态设置为1 用户状态表:-用户状态 +---------+--------+ | user_id | status | +=========+========+ | 1 | 1 | +---------+--------+ 用户表:-用户 +---------+---------------+---------------------+ |

当数据库列和检查条件中有多个值时,如何执行WHERE NOT IN条件

如果用户不属于excludedUserGroup,我想将其状态设置为1

用户状态表:-用户状态

+---------+--------+
| user_id | status |
+=========+========+
| 1       | 1      |
+---------+--------+
用户表:-用户

+---------+---------------+---------------------+
| user_id | user_group_id | secondary_group_ids |
+=========+===============+=====================+
| 1       | 4             | 2,8,9               |
+---------+---------------+---------------------+
变量:-

$excludeUsergroups = "8,7,12"
$finalExcludeUsergroups = implode(",", $excludeUsergroups);
我要执行的查询是:-

更新用户\u状态
在us上左加入用户u.user=u.user
设置us.status=1
其中(u.user\u group\u id不在(“.finalExcludeUsergroups.”)中,u.secondary\u group\u id不在(“.finalExcludeUsergroups.”)中)
现在的问题是,u.secondary\u group\u id和$finalExcludedUsergroups都有多个值,它在检查第二个不在时给出错误。

它只包含1个值,因此会检查用户\u组\u id,但当它转到辅助\u组\u id时会失败

如何执行第二个NOT IN,它将检查辅助组ID的每个值,并使用$FinalExcludeUserGroups进行检查

更新 我使用FIND_IN_SET进行了测试,但是它不起作用,因为FIND_IN_SET检查字符串列表中的字符串
FIND_IN_SET(字符串,字符串列表)


但是在我的例子中,我想检查字符串列表中的字符串列表,这在查找列表中是不可能的。

我对您的问题很感兴趣,想知道一个简单的用户定义函数是否有帮助,所以准备下面的示例。如果在数据库中创建函数,则应该能够在查询中向其传递两个“逗号分隔值”字符串,以查看是否共享了任何组。正如您所注意到的,我将其命名为否定格(即不相交),因为我无法很快想出一个合适的短名称来表示肯定格(即集合\u有\u一个\u或\u多个\u元素\u共同点似乎有点长!)

希望有人在某个时候会发现这很有用

/*
    MySQL Function to determine whether two comma-separated strings
    supplied as parameters share any common elements.
    
    Example Usage: 
    SELECT SETS_ARE_DISJOINT('8,7,12', '2,8,9'); --> False - shared entry = 8
    SELECT SETS_ARE_DISJOINT('7,12', '2,8,9');   --> True  - no shared entries
    
*/
CREATE FUNCTION SETS_ARE_DISJOINT(csv1 TEXT, csv2 TEXT)
  RETURNS BOOLEAN
  LANGUAGE SQL
BEGIN
    DECLARE Occurrences INT;
    DECLARE myValue TEXT;
    SET Occurrences = LENGTH(TRIM(csv1)) - LENGTH(REPLACE(TRIM(csv1), ',', ''));
Loop1:
    WHILE Occurrences > 0 DO
        SET myValue = SUBSTRING_INDEX(csv1, ',', 1);
        IF (myValue != '') THEN
            IF FIND_IN_SET(myValue , csv2) > 0 THEN
               RETURN FALSE;
            END IF;
        ELSE
            LEAVE Loop1; 
        END IF;
        SET Occurrences = LENGTH(TRIM(csv1)) - LENGTH(REPLACE(TRIM(csv1), ',', ''));
        IF (Occurrences = 0) THEN 
            LEAVE Loop1; 
        END IF;
        SET csv1 = SUBSTRING(csv1, LENGTH(SUBSTRING_INDEX(csv1, ',', 1)) + 2);
    END WHILE;
    RETURN TRUE;
END;

我对你的问题很感兴趣,想知道一个简单的用户定义函数是否有帮助,所以准备了下面的示例。如果在数据库中创建函数,则应该能够在查询中向其传递两个“逗号分隔值”字符串,以查看是否共享了任何组。正如您所注意到的,我将其命名为否定格(即不相交),因为我无法很快想出一个合适的短名称来表示肯定格(即集合\u有\u一个\u或\u多个\u元素\u共同点似乎有点长!)

希望有人在某个时候会发现这很有用

/*
    MySQL Function to determine whether two comma-separated strings
    supplied as parameters share any common elements.
    
    Example Usage: 
    SELECT SETS_ARE_DISJOINT('8,7,12', '2,8,9'); --> False - shared entry = 8
    SELECT SETS_ARE_DISJOINT('7,12', '2,8,9');   --> True  - no shared entries
    
*/
CREATE FUNCTION SETS_ARE_DISJOINT(csv1 TEXT, csv2 TEXT)
  RETURNS BOOLEAN
  LANGUAGE SQL
BEGIN
    DECLARE Occurrences INT;
    DECLARE myValue TEXT;
    SET Occurrences = LENGTH(TRIM(csv1)) - LENGTH(REPLACE(TRIM(csv1), ',', ''));
Loop1:
    WHILE Occurrences > 0 DO
        SET myValue = SUBSTRING_INDEX(csv1, ',', 1);
        IF (myValue != '') THEN
            IF FIND_IN_SET(myValue , csv2) > 0 THEN
               RETURN FALSE;
            END IF;
        ELSE
            LEAVE Loop1; 
        END IF;
        SET Occurrences = LENGTH(TRIM(csv1)) - LENGTH(REPLACE(TRIM(csv1), ',', ''));
        IF (Occurrences = 0) THEN 
            LEAVE Loop1; 
        END IF;
        SET csv1 = SUBSTRING(csv1, LENGTH(SUBSTRING_INDEX(csv1, ',', 1)) + 2);
    END WHILE;
    RETURN TRUE;
END;

我会使用MySql
而不是REGEXP
和正则表达式
/(^ | \,)3($| \,)/

:id
参数设置为
$finalExcludeUsergroups
, 我会举一个例子说明如何使用,但不知道您是否在使用mysqli、pdo、框架等等

正则表达式的分解:

  • (^ |\,)
    将匹配字符串的开头或逗号
  • 3
    将匹配您要查找的id(对于代码,我将在此处使用参数)
  • ($\124;\,)
    将匹配字符串或逗号的结尾

我会使用MySql
而不是REGEXP
和正则表达式
/(^ | \,)3($| \,)/

:id
参数设置为
$finalExcludeUsergroups
, 我会举一个例子说明如何使用,但不知道您是否在使用mysqli、pdo、框架等等

正则表达式的分解:

  • (^ |\,)
    将匹配字符串的开头或逗号
  • 3
    将匹配您要查找的id(对于代码,我将在此处使用参数)
  • ($\124;\,)
    将匹配字符串或逗号的结尾

好的,我通过foreach循环实现了我想要做的事情,我循环了$finalExcludeUsergroups,创建了FIND_IN_集合的数组,然后将其包含在查询中


foreach ($excludeUsergroups as $usergroup)
        {
            $statusJoiner[] = 'FIND_IN_SET(' . $db->quote($usergroup) .' , user.secondary_group_ids) = 0';
        }

然后我加入了他们的行列

if (!empty($statusJoiner))
        {
            //Joiner for hit part
            $Joiner = ' AND ';
            $statusFinalJoiner = implode($Joiner,$statusJoiner);
        }
然后查询如下所示:-

Update user_status us 
    LEFT JOIN user u ON us.user = u.user 
    SET us.status = 1
    WHERE (u.user_group_id NOT IN (". $finalExcludeUsergroups . ") AND " . $statusFinalJoiner . ")

就是这样,结果是:)

好的,所以我通过foreach循环实现了我想要做的事情,我循环了$finalExcludeUsergroups,创建了FIND_IN_集合的数组,然后将其包含在查询中


foreach ($excludeUsergroups as $usergroup)
        {
            $statusJoiner[] = 'FIND_IN_SET(' . $db->quote($usergroup) .' , user.secondary_group_ids) = 0';
        }

然后我加入了他们的行列

if (!empty($statusJoiner))
        {
            //Joiner for hit part
            $Joiner = ' AND ';
            $statusFinalJoiner = implode($Joiner,$statusJoiner);
        }
然后查询如下所示:-

Update user_status us 
    LEFT JOIN user u ON us.user = u.user 
    SET us.status = 1
    WHERE (u.user_group_id NOT IN (". $finalExcludeUsergroups . ") AND " . $statusFinalJoiner . ")

就是这样,结果是:)

我建议规范化您的数据模型。辅助组中的每个值都应存储在单独的表中的单独行中。然后,问题变得更容易解决。这就是为什么我们使用“数据库规范化”:是的,但是我不能这样做。在这种情况下,我使用的框架遵循这种结构,使用
FIND\u in\u SET
作为第二个子句。我假设数据是用逗号分隔的?@floGalen我在不同的答案中找到了FIND_IN_SET方法,但不明白它在这种情况下是如何工作的。我以前从未使用过它,查看过mysql文档,但不理解它。我建议您规范化数据模型。辅助组中的每个值都应存储在单独的表中的单独行中。然后,问题变得更容易解决。这就是为什么我们使用“数据库规范化”:是的,但是我不能这样做。在这种情况下,我使用的框架遵循这种结构,使用
FIND\u in\u SET
作为第二个子句。我假设数据是用逗号分隔的?@floGalen我在不同的答案中找到了FIND_IN_SET方法,但不明白它在这种情况下是如何工作的。我以前从未使用过它,查看过mysql文档,但不理解它。那么你是说如果我有一个字符串'8,9,14',并且我使用正则表达式将:id替换为(比如)'9,11,20,22',结果将为“false”(因为两个字符串中都存在9),而如果我将:id替换为'10,11,12,20',结果将为“true”(没有共同的数字)?我想