MySql DELETE используя SUBQUERY с той же таблицей в FROM

Система администратор базы данных: MySql 5.7.11

Я стараюсь создавать консультацию SQL, чтобы удалять все реестры, которые выполняют следующее условие:

Говорится о системе тарифов, таблица тариф связана с таблицей цены в связи один один uno-a-muchos, и каждая цена связана с продуктом.

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

DELETE p 
    FROM  ges_precio as p 
    WHERE p.tarifa_id = :tarifa 
          and id < 
              (select max(a.id) as id 
               from ges_precio  a 
               where a.tarifa_id = :tarifa 
                     and p.producto_id = a.producto_id 
               )

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

You can't specify target table 'p' for update in FROM clause

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

Я ищу способ реализовывать консультацию, не используя subquery в FROM что консультировал в таблицу цену.

ОБНОВЛЕНИЕ:

Я буду помещать пример для того, чтобы было понятно лучше, что я стремлюсь к тому, чтобы сделать, это таблица ges_precio:

пойдите | сумма | tarifa_id | producto_id

1 | 24 | 1 | 24

2 | 16 | 1 | 53

3 | 18 | 1 | 24

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

пойдите | сумма | tarifa_id | producto_id

2 | 16 | 1 | 53

3 | 18 | 1 | 24

4
задан 23.05.2017, 15:39
1 ответ

У меня был несколько раз этот тип проблемы (поддерживать последний реестр связи). Форма, что я это решил почти всегда, была с временными подмостками и queries укрытые.

CREATE TEMPORARY TABLE temp
  SELECT id FROM ges_precio 
  WHERE tarifa_id = ?? AND product_id = ??; -- [1]

DELETE FROM ges_precio 
  WHERE id < (SELECT MAX(id) FROM temp) 
  AND product_id = ??; -- [2]

DROP TEMPORARY TABLE temp; -- [3]

Этого он формирует:

  1. Ты создаешь временную таблицу со всеми ценами для тарифа и специфического продукта.
  2. Ты удаляешь все элементы, которые меньше по последней цене (MAX(id))
  3. Ты удаляешь временную таблицу.

Обновление:

Ввиду темы эффективности, которую он предлагает Javi2EE, я пишу какие-то предложения прогресса, который приходит мне в голову:

Сначала, временные подмостки - подмостки, которые существуют в оперативном запоминающем устройстве в течение выполнения query, у них есть максимальный размер и они работоспособные в использовании, так как они не используют диск (читать секцию temporary table)

В случае, если он прокрутит изображение в окне несколько раз в день (в cron чистоты, например). Мне приходит в голову следующее:

CREATE TEMPORARY TABLE temp
  SELECT MAX(id) as id, tarifa_id, producto_id 
  FROM ges_precio 
  GROUP BY tarifa_id, producto_id; -- Crear una tabla con solo los id de precio más altos, así se baja la cantidad total de filas de la tabla temporal.

DELETE g FROM ges_precio g
  WHERE id < (SELECT id FROM temp t WHERE t.tarifa_id = g.tarifa_id AND t.producto_id = g.producto_id ); -- y se borra usando un INNER JOIN con la temporal

DROP TEMPORARY TABLE temp; -- [3]

Другой выбор состоит в том, чтобы использовать переменные в связи вместо временных подмостков, так ты мог бы скроллировать этот query несколько раз, без беспокойства использования многих временных подмостков. Пример:

SET @id_temp = NULL;

SELECT MAX(a.id) INTO @id_temp 
  FROM ges_precio
  WHERE tarifa_id = :tarifa 
    AND producto_id = :producto_id;

DELETE FROM ges_precio 
  WHERE id < @id_temp;

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

Я надеюсь помочь с вышеупомянутым.

6
ответ дан 24.11.2019, 13:52
  • 1
    Спасибо за ответ Пабло, - первый soluci и # 243; n реальный, который я вижу перед этим situaci и # 243; n, хотя меня волнует немного тема эффективности этой консультации, так как тарифы состоят из десятков тысяч продуктов, и не, как будет реагировать база данных, будучи должен создавать столько временных подмостков. – Javi2EE 12.07.2016, 21:18
  • 2
    @Javi2EE обновлять и # 233; post с прогрессом, который приходит в голову мне. – Pablo Alcantar 13.07.2016, 10:57
  • 3
    крэк!! большое спасибо из-за ampliaci и # 243; n, три решения вторая справедливая то, в чем он нуждался. Есть один согрешите и # 241; или неудача, нет она g в DELETE g FROM ges_precio g. mill и # 243; n спасибо – Javi2EE 13.07.2016, 13:45

Теги

Похожие вопросы