Ошибка ссылки на основную таблицу в подзапросе поиска для обновления - PullRequest
0 голосов
/ 27 октября 2018

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

Мне нужно обновить записи таблицы с неправильной датой (1970-01-01), используя данные следующей записи (в соответствии с полем gkey, которое является последовательным в первичном ключе int).

Итак, если я сделаю этот запрос:

SELECT aa.gkey,
       aa.course_date,
       (select course_date from BI.fact_training_event_tbl bb where bb.gkey = (
            select min(cc.gkey) 
            from BI.fact_training_event_tbl cc 
                 where cc.gkey > aa.gkey)) as next_date
from BI.fact_training_event_tbl aa
where course_date = '1970-01-01'

Приводит записи правильно, как и ожидалось:

gkey   course_date  next_date
====   ===========  =========
4103   1970-01-01   2017-03-23
4884   1970-01-01   2017-03-22
5047   1970-01-01   2017-03-23

Теперь мне нужно обновить поле course_date с помощью next_date, но если я попытаюсь выполнить следующее:

update BI.fact_training_event_tbl aa
    set course_date =
    (select course_date from BI.fact_training_event_tbl bb where bb.gkey = (
            select min(cc.gkey)
    from BI.fact_training_event_tbl cc
         where cc.gkey > BI.fact_training_event_tbl.gkey))
where course_date = '1970-01-01'

Я получаю ошибку:

Код ошибки 1093. Невозможно указать целевую таблицу 'BI.fact_training_event_tbl' для обновления в предложении FROM

Я попытался сделать то, что рекомендуется здесь: Ошибка MySQL 1093 - Невозможно указать целевую таблицу для обновления в предложении FROM , вложив запрос в другой:

update BI.fact_training_event_tbl as zz
    set course_date =
    (select course_date from
    (select course_date from BI.fact_training_event_tbl as bb where bb.gkey = (
            select min(cc.gkey) 
      from BI.fact_training_event_tbl as cc
           where cc.gkey > gkey)) as aa )
where course_date = '1970-01-01'

но все, что я получаю, это установил date_course как ноль, а не next_date.

И если я попытаюсь сослаться на главную таблицу следующим образом:

where cc.gkey > BI.fact_training_event_tbl.gkey

или

where cc.gkey > zz.gkey

Там написано: Неизвестный столбец BI.fact_training_event_tbl.gkey или zz.gkey.

Есть идеи, как мне это осуществить?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Отчет о последнем сработавшем запросе, спасибо за solarflare за решение:

update fact_training_event_tbl orig
join ( SELECT aa.gkey,
    aa.course_date,
    (select course_date from BI.fact_training_event_tbl bb where bb.gkey = (
            select min(cc.gkey) from BI.fact_training_event_tbl cc where cc.gkey > aa.gkey)) as next_date
from BI.fact_training_event_tbl aa
where course_date = '1970-01-01' ) base
on base.gkey = orig.gkey
set orig.course_date = base.next_date
0 голосов
/ 27 октября 2018

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

Несмотря на то, что вы нашли обходные пути, они просто добавляют слой select вокруг исходного подзапроса, например, select * from (your original subquery), вы пропустили причину, по которой они работают: они используют производную таблицу вместо (зависимого) подзапроса (что и имел в виду @Cheekysoft для неявной временной таблицы в вашем связанном ответе ). Производная таблица не может зависеть от внешнего запроса (поэтому основная проблема исчезла). С ним более или менее обращаются, как с любой реальной таблицей (обратите внимание, например, что необходимо назвать производную таблицу, в вашем случае aa; см., Например, еще один мой ответ для некоторых других подробности об этом).

Но это также означает, что вы не можете использовать здесь какую-либо зависимость от внешней таблицы, независимо от того, как вы хотите обмануть MySQL. Вы, например, получите unknown column -error, потому что внешний запрос просто недоступен для ссылки на данный момент.

Таким образом, основная стратегия состоит в том, чтобы поместить все строки, которые вам когда-либо понадобятся, в производную таблицу, а затем выполнить команду join, чтобы выбрать строку, необходимую для обновления фактической строки:

update fact_training_event_tbl
join ( your original select that returns 3 rows ) base
on base.gkey = fact_training_event_tbl.gkey
set course_date = base.course_date

«Внутри» производной таблицы (base) вы можете делать все, что захотите, и использовать fact_training_event_tbl так часто, как хотите, но зависимость от external fact_training_event_tbl закончена » вне "1030 * по on условию.

Поскольку не только base является (производной) таблицей, но fact_training_event_tbl также является (фактической) таблицей, обычно также можно сделать

update fact_training_event_tbl
join fact_training_event_tbl base
on base.gkey = fact_training_event_tbl.gkey + 1
set course_date = base.course_date

В вашем случае это сработало бы, если вы имели в виду "поле gkey, которое является последовательным по первичному ключу" буквально (без пробелов). Но даже если это не так, он должен иллюстрировать аналогию между использованием обычной и производной таблиц в этой ситуации.

...