Решение для ошибки "подзапрос возвращает более 1 строки"

У меня есть один запрос, который возвращает несколько строк, и другой запрос, в котором я хочу установить критерии как одно из значений из этих нескольких строк, поэтому я хочу, чтобы подзапрос выглядел примерно так:

select * 
from table
where id= (multiple row query);

Где multiple row query возвращает несколько строк. Поэтому, если значения из этих строк равны 1,2,3, тогда я хочу установить id равным 1 или 2 или 3.

Ответы

Ответ 1

= может использоваться, когда подзапрос возвращает только 1 значение.

Когда подзапрос возвращает более 1 значения, вам придется использовать IN:

select * 
from table
where id IN (multiple row query);

Например:

SELECT *
FROM Students
WHERE Marks = (SELECT MAX(Marks) FROM Students)   --Subquery returns only 1 value

SELECT *
FROM Students
WHERE Marks IN 
      (SELECT Marks 
       FROM Students 
       ORDER BY Marks DESC
       LIMIT 10)                       --Subquery returns 10 values

Ответ 2

Вы можете использовать in():

select * 
from table
where id in (multiple row query)

или используйте соединение:

select distinct t.* 
from source_of_id_table s
join table t on t.id = s.t_id
where <conditions for source_of_id_table>

Соединение никогда не худший выбор для производительности, и в зависимости от конкретной ситуации и используемой базы данных может дать гораздо лучшую производительность.

Ответ 3

используйте MAX в вашем SELECT чтобы вернуть значение. ПРИМЕР

INSERT INTO school_year_studentid (student_id,syr_id) VALUES
((SELECT MAX(student_id) FROM student), (SELECT MAX(syr_id) FROM school_year))

вместо

INSERT INTO school_year_studentid (student_id,syr_id) VALUES
((SELECT (student_id) FROM student), (SELECT (syr_id) FROM school_year))

попробуйте это без MAX, это будет больше чем одно значение

Ответ 4

Когда появляется ошибка "подзапрос возвращает более 1 строки", база данных фактически сообщает вам, что существует неразрешимая циклическая ссылка. Это немного похоже на использование электронной таблицы и произнесение ячейки A1 = B1, а затем произнесение B1 = A1. Эта ошибка обычно связана со сценарием, в котором требуется двойной вложенный подзапрос. Я бы порекомендовал вам поискать вещь, называемую " запрос кросс-таблицы ", это тип запроса, который обычно необходим для решения этой проблемы. Это в основном внешнее соединение (левое или правое), вложенное в подзапрос или наоборот. Эту проблему также можно решить с помощью двойного объединения (также считается типом запроса кросс-таблицы), например, ниже:

CREATE DEFINER='root'@'localhost' PROCEDURE 'SP_GET_VEHICLES_IN'(
    IN P_email VARCHAR(150),
    IN P_credentials VARCHAR(150)
)
BEGIN
    DECLARE V_user_id INT(11);
    SET V_user_id = (SELECT user_id FROM users WHERE email = P_email AND credentials = P_credentials LIMIT 1);
    SELECT vehicles_in.vehicle_id, vehicles_in.make_id, vehicles_in.model_id, vehicles_in.model_year,
    vehicles_in.registration, vehicles_in.date_taken, make.make_label, model.model_label
    FROM make
    LEFT OUTER JOIN vehicles_in ON vehicles_in.make_id = make.make_id
    LEFT OUTER JOIN model ON model.make_id = make.make_id AND vehicles_in.model_id = model.model_id
    WHERE vehicles_in.user_id = V_user_id;
END

В приведенном выше коде обратите внимание, что в предложении SELECT есть три таблицы, и эти три таблицы появляются после предложения FROM и после двух предложений LEFT OUTER JOIN, эти три таблицы должны быть различны среди предложений FROM и LEFT OUTER JOIN, чтобы синтаксически правильно.

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

Еще одна вещь, о которой я должен предупредить: если вы собираетесь использовать кросс-таблицу как часть рабочей системы, а не просто как периодический отчет, вы должны проверить количество записей и перенастроить условия объединения, пока не будет возвращено минимальное количество записей, в противном случае большие таблицы и кросс-таблицы могут привести к остановке вашего сервера. Надеюсь это поможет.