Nano Hash - криптовалюты, майнинг, программирование

Ошибка ссылки на основную таблицу в подзапросе поиска для обновления

Прежде всего, на этот вопрос нет ответа ранее, так как ветка об ошибке 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 как null, а не next_date.

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

where cc.gkey > BI.fact_training_event_tbl.gkey

or

where cc.gkey > zz.gkey

Пишет: Неизвестный столбец BI.fact_training_event_tbl.gkey или zz.gkey.

Любые идеи о том, как я могу осуществить это?


Ответы:


1

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

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

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

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

27.10.2018
  • Блестящий. Я OOF на выходные, но я проверю это первым делом в понедельник утром и отчитаюсь. Это именно то, что мне нужно. Большое спасибо за Вашу помощь. 28.10.2018
  • Выдающийся! Оно работало завораживающе. Окончательный запрос ниже. Большое спасибо. 29.10.2018

  • 2

    Сообщая об окончательном сработавшем запросе, спасибо 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
    
    29.10.2018
    Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..