select tf.id from text_fields as tf WHERE tf.study_id NOT IN (select id from studies)
Я использую это, чтобы найти осиротевшие записи, и он отлично работает.
Однако, когда я пытаюсь присвоить результат var, используя SET
, я получаю ошибку "Subquery возвращает более 1 строки".
SET @text_field_ids := (select tf.id from text_fields as tf WHERE tf.study_id NOT IN (select id from studies))
Для контекста я хочу использовать записи var, а затем text_fields, например
DELETE from text_fields WHERE id IN @text_field_ids
Кстати, я попытался передать подзапрос непосредственно DELETE, например:
DELETE from text_fields WHERE id IN (select id from text_fields as tf WHERE tf.study_id NOT IN (select id from studies))
Но это дает ошибку. You can't specify target table 'text_fields' for update in FROM clause
потому что, по-видимому, вы не можете использовать You can't specify target table 'text_fields' for update in FROM clause
таблицу из предложения WHERE.
Обычный способ обхода ERROR 1093 (HY000): таблица "ПОЛЬЗОВАТЕЛИ" указана дважды, как в качестве цели для "DELETE", так и в качестве отдельного источника для ошибки данных - нажать немного более глубже, например, увидеть второе удаление [CN10 ]
MariaDB [sandbox]> SELECT ID FROM USERS;
+----+
| ID |
+----+
| 1 |
| 2 |
| 3 |
| 6 |
| 7 |
| 8 |
| 10 |
| 12 |
| 14 |
| 15 |
| 16 |
| 17 |
| 18 |
| 19 |
+----+
14 rows in set (0.00 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> DELETE FROM USERS
-> WHERE ID IN (SELECT ID FROM USERS WHERE ID IN (18,19))
-> ;
ERROR 1093 (HY000): Table 'USERS' is specified twice, both as a target for 'DELETE' and as a separate source for data
MariaDB [sandbox]>
MariaDB [sandbox]> DELETE FROM USERS
-> WHERE ID IN (SELECT ID FROM (SELECT ID FROM USERS WHERE ID IN (18,19)) U )
-> ;
Query OK, 2 rows affected (0.11 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> SELECT ID FROM USERS;
+----+
| ID |
+----+
| 1 |
| 2 |
| 3 |
| 6 |
| 7 |
| 8 |
| 10 |
| 12 |
| 14 |
| 15 |
| 16 |
| 17 |
+----+
12 rows in set (0.00 sec)
Вы можете использовать временную таблицу:
create temporary table if not exists mytmptable select tf.id as id from text_fields as tf WHERE tf.study_id NOT IN (select id from studies)
и затем вы можете использовать его в delete:
DELETE from text_fields WHERE id IN (select Id from mytmptable)
Поскольку запрос
select tf.id from text_fields as tf WHERE tf.study_id NOT IN (select id from studies)
возвращает более 1 строки, присваивая набор записей переменной с ошибкой. однако, если вам действительно нужно назначить его переменной, вы можете сделать это как
select 'tf'.'id' from 'text_fields' as tf WHERE 'tf'.'study_id' NOT IN
(select 'id' from 'studies') into @text_field_ids;
или же
SELECT @text_field_ids := 'tf'.'id' from 'text_fields' as tf WHERE 'tf'.'study_id' NOT IN
(select 'id' from 'studies');
подробнее об этом здесь
В качестве альтернативы, если ваш пользователь db создал временную таблицу priviliges, вы можете создать временную таблицу, чтобы выбрать свои записи, которые будут проживать в вашей сессии. Обратите внимание, что для того, чтобы не пострадать от штрафа за производительность, временная таблица создается с помощью механизма памяти.
CREATE TEMPORARY TABLE IF NOT EXISTS temp_table ( INDEX('id') )
ENGINE=Memory
AS (
select 'tf'.'id' from 'text_fields' as 'tf' WHERE 'tf'.'study_id' NOT IN (select 'id' from 'studies')
);
# and remove the records with
delete from 'text_fields' where id in (select 'id' from 'temp_table')
Result consisted of more than one row
:)
DELETE from text_fields WHERE id IN (select tf.id from text_fields as tf WHERE tf.study_id NOT IN (select id from studies))