Оператор MySQL IN() не работает

Как использовать оператор 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 (Students)" возвращает 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.

3 ответа

Решение

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

Повторим еще раз: сохранение "списка через запятую" в столбце - это не шаблон; он противоречит реляционной теории и нормализации и игнорирует лучшие практики в отношении реляционных баз данных. О

Кто-то может поспорить за улучшение производительности, но этот шаблон не улучшает производительность; скорее это добавляет ненужную сложность в запрос и операции DML.

Вам нужно три стола. Один стол 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" для фона на этом.

РЕДАКТИРОВАТЬ

Я знаю, что вы специально не запрашиваете другую структуру таблицы, но это способ иметь тип данных (одно число), который работает с IN, Пожалуйста, поверьте мне, это правильный способ сделать это, потому что у вас возникли проблемы с чем-то простым IN в том, что вы используете нестандартный подход, который для такой стандартной проблемы, как правило, не очень хорошая идея.

Это не то, как должна работать функция IN. Вы используете IN, когда у вас есть список возможных совпадений, таких как:

вместо:

WHERE id=1 or id=2 or id=3 or id=4

ты используешь:

WHERE id IN (1,2,3,4)

Во всяком случае, ваша логика не верна. Соотношение класса и ученика - "многие ко многим", поэтому необходима третья таблица. Давайте назовем это 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";
Другие вопросы по тегам