如何使用IN()运算符不能正常工作。
这些表是示例,看起来与我拥有的真实数据库相同。我没有允许添加表格或更改
这些是表格:
students
+------+------+
| id | name |
+------+------+
| 1 | ali |
| 2 | man |
| 3 | sos |
+------+------+
Classes
+------+---------+
| c_id | students|
+------+---------+
| 1 | 1,2,3,4 |
| 2 | 88,33,55|
| 3 | 45,23,72|
+------+---------+
当我使用此查询时,它只返回id为1的学生 因为“ id IN(学生)”在第一个值相等时返回1。
select name,c_id from students,classes where id IN (students);
当我在PHP上获取列表而不是添加它。它工作正常。但是,这个解决方案需要一个循环并且需要花费很多查询。
select name,c_id from students,classes where id IN (1,2,3,4);
FIND_IN_SET()
同样的情况发生,它只返回1,但如果其他位置的值返回0。
答案 0 :(得分:4)
IN
运算符运行正常,适用于它的功能。
首先,考虑重组数据以进行规范化,并避免将值存储为逗号分隔列表。
其次,如果您必须处理包含逗号分隔值列表的列,MySQL会提供 FIND_IN_SET()
函数。
<强>后续强>
抛弃连接操作的旧式逗号语法,改为使用JOIN
关键字。并将连接谓词从WHERE子句重定位到ON子句。完全限定列引用,例如
SELECT s.name
, c.c_id
FROM students s
JOIN classes c
ON FIND_IN_SET(s.student_id,c.students)
ORDER BY s.name, c.c_id
重申一下,存储一个以逗号分隔的列表&#34;在列中是反模式;它反对关系理论和规范化,并忽视关系数据库的最佳实践。 0
有人可能会争取提高性能,但这种模式并没有提高性能;相反,它会增加查询和DML操作的不必要的复杂性。
答案 1 :(得分:2)
你需要三张桌子。
一个表格students
,一个表格classes
,然后是一个表格,例如students_to_classes
包含类似
c_id | student_id
1 | 1
1 | 2
1 | 3
1 | 4
2 | 88
等等。 然后你可以查询
select c_id from students_to_classes where student_id in (1,2,3,4)
Google“n:m relationship”的背景知识。
修改
我知道你不是专门要求另一个表结构,但这是一种使用IN
的数据类型(单个数字)的方法。请相信我这是正确的方法,你遇到像IN
这样简单的问题的原因是你使用的是非标准的方法,对于这样的标准问题,通常不是一个好主意。
答案 2 :(得分:0)
这不是函数IN应该如何工作。如果您有可能的匹配列表,请使用IN:
而不是:
WHERE id=1 or id=2 or id=3 or id=4
你使用:
WHERE id IN (1,2,3,4)
无论如何,你的逻辑不正确。 Class和Student的关系是多对多的,因此需要第三个表。我们称之为studend_class
,您可以在其中存储每个班级的学生。
student
+------+------+
| id | name |
+------+------+
| 1 | ali |
| 2 | man |
| 3 | sos |
+------+------+
class
+------+---------+
| id | name |
+------+---------+
| 1 | math |
| 2 | english |
| 3 | science |
+------+---------+
student_class
+------------+-------------+
| class_id | student_id |
+------------+-------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 3 | 3 |
+--------------+-----------+
在上面的例子中,所有学生都在数学课上,而阿里也在科学课上。
最后,如果你想知道哪些学生在哪个班级,让我们说数学,你可以使用:
SELECT s.id, s.name, c.name
FROM student s
INNER JOIN student_class sc ON sc.student_id=s.id
INNER JOIN class c ON sc.class_id = c.id
WHERE c.name="math";