2013-06-26 3 views
2

У меня есть таблица, которая содержит список пользователей и приложений, к которым им разрешен доступ. Каждая строка в этой таблице имеет столбец для user_id и app_id вместе с некоторыми другими материалами, и наличие такой строки достаточно для того, чтобы каждый пользователь мог получить доступ к этому приложению.subquery возвращает более одной ошибки строки в mysql

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

Было бы что-то вроде этого:

SET @v1 := (SELECT user_id from user_app_map WHERE app_id != <app_id_here>); 

INSERT INTO user_app_map (user_id, app_id) VALUES (
    (SELECT @v1), <app_id_here>); 

Когда я выполнения запроса выше, я получаю сообщение об ошибке #1242 - Subquery returns more than 1 row.

Я искал эту ошибку в Google, но результаты, которые у меня были, были проблемой, которая была более сложной, чем эта, поэтому я не мог понять, чего я хотел от этого.

Пожалуйста, расскажите, как я могу совершить такую ​​операцию?

Заранее благодарен!

UPDATE: Я мог бы сделать это следующим образом:

INSERT INTO user_app_map (user_id, app_id) 
    SELECT user_id, <app_id_here> from user_app_map WHERE app_id != <app_id_here> 

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

Пример: пользователь 3 может иметь доступ к приложениям 3 и 4 приложениям, что означает, что user_app_map содержит две строки с user_id 3 и app_id 3 и 4 каждый. С приведенным выше запросом я получаю user_id из второй строки и снова создаю еще одну строку, которая была бы ненужным дубликатом первой строки.

ответ

2

можно присвоить только одно значение переменной, так что, если этот запрос:

SELECT user_id from user_app_map WHERE app_id != <app_id_here> 

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

Чтобы это исправить, либо обеспечить только один ряд, возможно, на использовании агрегатной функции:

SET @v1 := (SELECT max(user_id) from user_app_map WHERE app_id != <app_id_here>); 

Или сузить строки к одному на более жесткие, где положение.


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

INSERT INTO user_app_map (user_id, app_id) 
SELECT DISTINCT user_id, <app_id_here> from user_app_map WHERE app_id != <app_id_here> 
+0

Да, это возвращает несколько строк. Как я могу сделать то же самое без использования переменной? –

+0

@ ForbiddenOverseer См. Отредактированный aswer – Bohemian

+0

Кажется, что-то не так с последним запросом ... Где заканчивается скобка после VALUES? –

2

Вы используете подзапрос в том месте, где, как ожидается, только один одно значение - отсюда и эта ошибка.

Но это легко можно сделать с помощью INSERT ... SELECT синтаксиса, например, так:

INSERT INTO user_app_map (user_id, app_id) 
    SELECT user_id, <app_id_here> from user_app_map WHERE app_id != <app_id_here> 

Выбрать, подберут user_id из соответствующих записей динамически, а второй «столбец» он возвращает только статическое значение.

+0

Ничего себе ... похоже, что этот только что решил мою проблему !! Я думал о написании этого запроса, но не работает инструкция SELECT каждый раз, когда INSERT был выполнен? Или он выбирает все записи один раз, а затем ВСТАВЛЯЕТ их в таблицу? Спасибо за помощь! Ожидание ответа. :) –

+0

См. Связанную страницу руководства, где говорится: _ «При одновременном выборе и вставке в таблицу MySQL создает временную таблицу для хранения строк из SELECT, а затем вставляет эти строки в целевую таблицу». _ – CBroe

+0

По некоторым причинам некоторые пользователи еще не получили доступ к приложениям. Использует ли WHERE app_id! = те, у которых app_id установлен в NULL? –