Получение ОШИБКИ 1093 (HY000) с использованием подзапроса

У меня есть следующая таблица:

--------------------------------------------------------------------------------
| id | pack_id | user_id |     start_date      |       end_date      | runtime |
--------------------------------------------------------------------------------
| 1  |    52   |   9     | 2019-04-09 11:53:00 | 2019-04-09 11:54:00 |   60    |
| 2  |    52   |   9     | 2019-04-09 11:58:00 |         NULL        |   NULL  |

Я хотел бы обновить end_date и runtime последнего идентификатора того же pack_id и user_id. end_date нужно взять текущую дату и время. Вот мой запрос:

UPDATE 
    myTable 
SET 
    end_date = NOW(),
    runtime = TIMESTAMPDIFF(SECOND, start_date, NOW()) 
WHERE 
    id = (
        SELECT 
            max(id) 
        FROM 
            myTable 
        WHERE 
            user_id = '9' 
        AND 
            pack_id = '52'
    )

И я получаю следующую ошибку:

ERROR 1093 (HY000) at line 1: You can't specify target table 'myTable' for update in FROM clause

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
0
38
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы не можете сделать это в MySQL, поэтому вместо этого используйте JOIN:

UPDATE myTable t JOIN
       (SELECT max(id) as max_id
        FROM myTable 
        WHERE user_id = '9' AND pack_id = '52'
       ) tt
       ON t.id = tt.max_id
    SET t.end_date = NOW(),
        t.runtime = TIMESTAMPDIFF(SECOND, t.start_date, NOW()) ;

Почему мы не можем сделать это в MySQL? Можем ли мы сделать это в других СУБД?

executable 09.04.2019 13:42

@исполняемый . . . Это ограничение MySQL (и оно также применимо к MariaDB). Ваша версия будет работать в любой другой базе данных.

Gordon Linoff 09.04.2019 14:14

использовать подзапрос глубже в предложении from

UPDATE 
    myTable 
SET 
    end_date = NOW(),
    runtime = TIMESTAMPDIFF(SECOND, start_date, NOW()) 
WHERE 
    id = (
 select id from (
        SELECT 
            max(id) as id
        FROM 
            myTable 
        WHERE 
            user_id = '9' 
        AND 
            pack_id = '52'
) a
    )

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

UPDATE myTable 
SET  end_date = NOW(),
    runtime = TIMESTAMPDIFF(SECOND, start_date, NOW()) 
WHERE id = (
select  max_id from (
        SELECT 
            max(id)  max_id  
        FROM  myTable 
        WHERE  user_id = '9' 
        AND pack_id = '52'

        ) t   )

или внутреннее соединение в подзапросе

UPDATE myTable m 
INNER JOIN (
        SELECT 
            max(id)  max_id  
        FROM  myTable 
        WHERE  user_id = '9' 
        AND pack_id = '52'

        ) t   ON t.max_id  =  m.id 

SET  end_date = NOW(),
    runtime = TIMESTAMPDIFF(SECOND, start_date, NOW()) 

Другие вопросы по теме