Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.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
任何人都可以在MySQL in子句中解释这一逻辑背后的原因_Mysql - Fatal编程技术网

任何人都可以在MySQL in子句中解释这一逻辑背后的原因

任何人都可以在MySQL in子句中解释这一逻辑背后的原因,mysql,Mysql,任何人都可以在MySQL in子句中解释这一逻辑的背后,并帮助我理解这个问题 我有一个用户表,该表的用户属于一个或多个组。 组表主键引用在users表中由逗号(,)分隔的值更新,如下所示 Query 1. SELECT * FROM user; +---------+-----------+-------------------------+-----------+ | user_id | user_name | user_email | group_id | +--

任何人都可以在MySQL in子句中解释这一逻辑的背后,并帮助我理解这个问题

我有一个用户表,该表的用户属于一个或多个组。 组表主键引用在users表中由逗号(,)分隔的值更新,如下所示

Query 1. SELECT * FROM user;
+---------+-----------+-------------------------+-----------+
| user_id | user_name | user_email              | group_id  |
+---------+-----------+-------------------------+-----------+
|       1 | suresh    | xxxx@yyyyyyyyyy.com     | 22        |
|       2 | sundar    | s7sundera@gmail.com     | 2         |
|       3 | tester    | xxxxxxxx@yyyyyyyyyy.com | 1,2,3,4   |
|       4 | gail      | zzzzzz@gmail.com        | 1,2,3,4,5 |
+---------+-----------+-------------------------+-----------+
若我在MySQL中使用IN子句和组id值作为2,那个么我只得到一个结果

Query 2. SELECT * FROM user WHERE group_id IN(2)
+---------+-----------+---------------------+----------+
| user_id | user_name | user_email          | group_id |
+---------+-----------+---------------------+----------+
|       2 | sundar    | s7sundera@gmail.com | 2        |
+---------+-----------+---------------------+----------+
如果我在MySQL中使用IN子句和组id值作为(1,2),我会得到三个结果

Query 3. SELECT * FROM user WHERE group_id IN(1,2)
+---------+-----------+-------------------------+-----------+
| user_id | user_name | user_email              | group_id  |
+---------+-----------+-------------------------+-----------+
|       2 | sundar    | s7sundera@gmail.com     | 2         |
|       3 | tester    | xxxxxxxx@yyyyyyyyyy.com | 1,2,3,4   |
|       4 | gail      | zzzzzz@gmail.com        | 1,2,3,4,5 |
+---------+-----------+-------------------------+-----------+
我希望获得组id 2用户,如以下输出,但它没有按预期工作

如果我使用这个查询,我需要得到查询3的结果,有可能吗

SELECT * FROM user WHERE group_id IN(2)

1,2
传递给
中的
操作符时,您要求
1
2
;这就是它将返回所有三个结果的原因。如果您有一个值以逗号分隔的列,则违反了标准格式;因为每列不应包含多个值。如果要在多值逗号分隔列中查找单个值,则可以使用
find\u in_SET

规范化架构如下所示:

+---------+-----------+-------------------------+ | user_id | user_name | user_email | +---------+-----------+-------------------------+ | 2 | sundar | s7sundera@gmail.com | | 3 | tester | xxxxxxxx@yyyyyyyyyy.com | | 4 | gail | zzzzzz@gmail.com | +---------+-----------+-------------------------+ +---------+-----------+ | user_id | group_id | +---------+-----------+ | 2 | 2 | | 3 | 1 | | 3 | 2 | | 3 | 3 | | 3 | 4 | | 4 | 1 | | 4 | 2 | | 4 | 3 | | 4 | 4 | | 4 | 5 | +---------+-----------+ +----------+ | group_id | +----------+ | 1 | | 2 | | 3 | | 4 | +----------+ +---------+-----------+-------------------------+ |用户id |用户名称|用户电子邮件| +---------+-----------+-------------------------+ |2 | sundar |s7sundera@gmail.com | |3 |测试仪|xxxxxxxx@yyyyyyyyyy.com | |4 |盖尔|zzzzzz@gmail.com | +---------+-----------+-------------------------+ +---------+-----------+ |用户id |组id| +---------+-----------+ | 2 | 2 | | 3 | 1 | | 3 | 2 | | 3 | 3 | | 3 | 4 | | 4 | 1 | | 4 | 2 | | 4 | 3 | | 4 | 4 | | 4 | 5 | +---------+-----------+ +----------+ |组id| +----------+ | 1 | | 2 | | 3 | | 4 |
+----------+ 将
1,2
传递给
中的
操作符时,您要求
1
2
;这就是它将返回所有三个结果的原因。如果您有一个值以逗号分隔的列,则违反了标准格式;因为每列不应包含多个值。如果要在多值逗号分隔列中查找单个值,则可以使用
find\u in_SET

规范化架构如下所示:

+---------+-----------+-------------------------+ | user_id | user_name | user_email | +---------+-----------+-------------------------+ | 2 | sundar | s7sundera@gmail.com | | 3 | tester | xxxxxxxx@yyyyyyyyyy.com | | 4 | gail | zzzzzz@gmail.com | +---------+-----------+-------------------------+ +---------+-----------+ | user_id | group_id | +---------+-----------+ | 2 | 2 | | 3 | 1 | | 3 | 2 | | 3 | 3 | | 3 | 4 | | 4 | 1 | | 4 | 2 | | 4 | 3 | | 4 | 4 | | 4 | 5 | +---------+-----------+ +----------+ | group_id | +----------+ | 1 | | 2 | | 3 | | 4 | +----------+ +---------+-----------+-------------------------+ |用户id |用户名称|用户电子邮件| +---------+-----------+-------------------------+ |2 | sundar |s7sundera@gmail.com | |3 |测试仪|xxxxxxxx@yyyyyyyyyy.com | |4 |盖尔|zzzzzz@gmail.com | +---------+-----------+-------------------------+ +---------+-----------+ |用户id |组id| +---------+-----------+ | 2 | 2 | | 3 | 1 | | 3 | 2 | | 3 | 3 | | 3 | 4 | | 4 | 1 | | 4 | 2 | | 4 | 3 | | 4 | 4 | | 4 | 5 | +---------+-----------+ +----------+ |组id| +----------+ | 1 | | 2 | | 3 | | 4 |
+----------+ 这太长了,不能作为注释,但您需要重新考虑当前的表设计。您不应将
组id
值存储为逗号分隔的列表

表的结构应类似于以下内容:

create table user
(
    user_id int,  PK
    user_name varchar(50),
    user_email varchar(100)
);

create table groups
(
    group_id int, PK
    group_name varchar(10)
);

create table user_group
(
    user_id int,
    group_id int
);
user\u-group
表将同时具有
user\u-id
group\u-id
的主键,因此您无法获得重复项,然后这些列应该是相应表的外键。此表允许您为每个用户id设置多个组

然后,当您查询表时,查询将是:

select u.user_id, 
  u.user_name,
  u.user_email,
  g.group_id
from user u
inner join user_group ug 
  on u.user_id = ug.user_id
inner join groups g
  on ug.group_id = g.group_id

如果出于显示目的需要在逗号分隔的列表中显示
group\u id
值,可以使用
group\u CONCAT()

如果重新设计表格,则搜索时会变得容易得多:

select u.user_id, 
  u.user_name,
  u.user_email,
  g.group_id
from user u
inner join user_group ug 
  on u.user_id = ug.user_id
inner join groups g
  on ug.group_id = g.group_id
where g.group_id in (1, 2)

请参见

这太长,不能作为注释,但您需要重新考虑当前的表设计。您不应将
组id
值存储为逗号分隔的列表

表的结构应类似于以下内容:

create table user
(
    user_id int,  PK
    user_name varchar(50),
    user_email varchar(100)
);

create table groups
(
    group_id int, PK
    group_name varchar(10)
);

create table user_group
(
    user_id int,
    group_id int
);
user\u-group
表将同时具有
user\u-id
group\u-id
的主键,因此您无法获得重复项,然后这些列应该是相应表的外键。此表允许您为每个用户id设置多个组

然后,当您查询表时,查询将是:

select u.user_id, 
  u.user_name,
  u.user_email,
  g.group_id
from user u
inner join user_group ug 
  on u.user_id = ug.user_id
inner join groups g
  on ug.group_id = g.group_id

如果出于显示目的需要在逗号分隔的列表中显示
group\u id
值,可以使用
group\u CONCAT()

如果重新设计表格,则搜索时会变得容易得多:

select u.user_id, 
  u.user_name,
  u.user_email,
  g.group_id
from user u
inner join user_group ug 
  on u.user_id = ug.user_id
inner join groups g
  on ug.group_id = g.group_id
where g.group_id in (1, 2)

请参见

MySQL将逗号分隔的列表视为字符串以外的任何东西。当您在(2)中执行
WHERE group\u id
时,它会将
group\u id
转换为
INT
,以便与
2
进行比较

当强制转换为
INT
时,MySQL在第一个非数字字符处停止

例如,(2)
中的
'1,2,3,4,5'变为(2)
中的
1。这是错误的

您可以尝试使用
FIND_IN_SET
来执行所需操作,但效率不高(因为它无法使用索引;它需要读取每一行以查看是否匹配)

要搜索多行,请使用

WHERE FIND_IN_SET(1, group_id) OR FIND_IN_SET(2, group_id)

正确的方法是为每个用户创建一个“链接表”,其中包含一(或多)行,显示他们所在的组。

MySQL不将逗号分隔的列表视为字符串以外的任何内容。当您在(2)中执行
WHERE group\u id
时,它会将
group\u id
转换为
INT
,以便与
2
进行比较

当铸造到
mysql> DROP DATABASE IF EXISTS sundar;
Query OK, 1 row affected (0.00 sec)

mysql> CREATE DATABASE sundar;
Query OK, 1 row affected (0.00 sec)

mysql> use sundar
Database changed
mysql> CREATE TABLE user
    -> (
    ->     id int not null auto_increment,
    ->     user_name VARCHAR(30),
    ->     user_email VARCHAR(70),
    ->     group_id VARCHAR(128),
    ->     PRIMARY KEY (id)
    -> );
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO user (user_name,user_email,group_id) VALUES
    -> ('suresh' , 'xxxx@yyyyyyyyyy.com'     ,'22'),
    -> ('sundar' , 's7sundera@gmail.com'     ,'2'),
    -> ('tester' , 'xxxxxxxx@yyyyyyyyyy.com' ,'1,2,3,4'),
    -> ('gail'   , 'zzzzzz@gmail.com'        ,'1,2,3,4,5');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql>
mysql> SELECT * FROM user;
+----+-----------+-------------------------+-----------+
| id | user_name | user_email              | group_id  |
+----+-----------+-------------------------+-----------+
|  1 | suresh    | xxxx@yyyyyyyyyy.com     | 22        |
|  2 | sundar    | s7sundera@gmail.com     | 2         |
|  3 | tester    | xxxxxxxx@yyyyyyyyyy.com | 1,2,3,4   |
|  4 | gail      | zzzzzz@gmail.com        | 1,2,3,4,5 |
+----+-----------+-------------------------+-----------+
4 rows in set (0.00 sec)

mysql>
SELECT user.* FROM
(SELECT * FROM (SELECT id,CONCAT(',',group_id ,',') group_ids
FROM user) U WHERE LOCATE(',1,',group_ids)) U1
INNER JOIN
(SELECT * FROM (SELECT id,CONCAT(',',group_id ,',') group_ids
FROM user) U WHERE LOCATE(',2,',group_ids)) U2
ON U1.id = U2.id
INNER JOIN user ON user.id = U2.id;
mysql> SELECT user.* FROM
    -> (SELECT * FROM (SELECT id,CONCAT(',',group_id ,',') group_ids
    -> FROM user) U WHERE LOCATE(',1,',group_ids)) U1
    -> INNER JOIN
    -> (SELECT * FROM (SELECT id,CONCAT(',',group_id ,',') group_ids
    -> FROM user) U WHERE LOCATE(',2,',group_ids)) U2
    -> ON U1.id = U2.id
    -> INNER JOIN user ON user.id = U2.id;
+----+-----------+-------------------------+-----------+
| id | user_name | user_email              | group_id  |
+----+-----------+-------------------------+-----------+
|  3 | tester    | xxxxxxxx@yyyyyyyyyy.com | 1,2,3,4   |
|  4 | gail      | zzzzzz@gmail.com        | 1,2,3,4,5 |
+----+-----------+-------------------------+-----------+
2 rows in set (0.00 sec)

mysql>
mysql> SELECT user.* FROM
    -> (SELECT * FROM (SELECT id,CONCAT(',',group_id ,',') group_ids
    -> FROM user) U WHERE LOCATE(',2,',group_ids)) U1
    -> INNER JOIN
    -> (SELECT * FROM (SELECT id,CONCAT(',',group_id ,',') group_ids
    -> FROM user) U WHERE LOCATE(',4,',group_ids)) U2
    -> ON U1.id = U2.id
    -> INNER JOIN user ON user.id = U2.id;
+----+-----------+-------------------------+-----------+
| id | user_name | user_email              | group_id  |
+----+-----------+-------------------------+-----------+
|  3 | tester    | xxxxxxxx@yyyyyyyyyy.com | 1,2,3,4   |
|  4 | gail      | zzzzzz@gmail.com        | 1,2,3,4,5 |
+----+-----------+-------------------------+-----------+
2 rows in set (0.00 sec)

mysql>