Решение для ошибки "подзапрос возвращает более 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, чтобы синтаксически правильно.
Следует отметить, что это очень важная конструкция, которую нужно знать как разработчику, особенно если вы пишете запросы периодических отчетов, и это, вероятно, самый важный навык для любой сложной перекрестной ссылки, поэтому все разработчики должны изучить эти конструкции (кросс-таблица и двойная таблица). присоединиться).
Еще одна вещь, о которой я должен предупредить: если вы собираетесь использовать кросс-таблицу как часть рабочей системы, а не просто как периодический отчет, вы должны проверить количество записей и перенастроить условия объединения, пока не будет возвращено минимальное количество записей, в противном случае большие таблицы и кросс-таблицы могут привести к остановке вашего сервера. Надеюсь это поможет.