RGB

[Решено] Один sql-запрос для удаления всех товаров по условию

Рекомендуемые сообщения

RGB    1 012

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

Я смог скомпоновать запрос, используя модель из модуля фильтра товаров в админке, получилось вот так (мультиязычность и префиксы убрал, так как у меня этого не нужно):

SELECT p.product_id FROM product p LEFT JOIN product_description pd ON (p.product_id = pd.product_id) LEFT JOIN manufacturer m ON (p.manufacturer_id = m.manufacturer_id) LEFT JOIN product_to_category p2c ON (p.product_id = p2c.product_id) WHERE p2c.category_id = '100' AND p.manufacturer_id = '50';

т.е. здесь выводятся ид всех товаров производителя 50 из категории 100. Для удаления есть запросы из ф-ции deleteProduct, которую вы все знаете

		$this->db->query("DELETE FROM " . DB_PREFIX . "product WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_attribute WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_description WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_discount WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_image WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_option WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_option_value WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE related_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_reward WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_to_download WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_to_layout WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "product_to_store WHERE product_id = '" . (int)$product_id . "'");
		$this->db->query("DELETE FROM " . DB_PREFIX . "review WHERE product_id = '" . (int)$product_id . "'");

Так вот, вопрос - как можно (и возможно ли вообще) объединить все эти делиты в один (у меня MySQL новее 4), чтобы не дублировать в условии для каждого из них верхний селект, а указать одно общее условие:

WHERE ... IN (SELECT p.product_id FROM product p LEFT JOIN product_description pd ON (p.product_id = pd.product_id) LEFT JOIN manufacturer m ON (p.manufacturer_id = m.manufacturer_id) LEFT JOIN product_to_category p2c ON (p.product_id = p2c.product_id) WHERE p2c.category_id = '100' AND p.manufacturer_id = '50');

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
freelancer    1 410


DELETE t1, t2, t3, ..., tn FROM product t1

LEFT JOIN product_to_category t2 ON(t1.product_id=t2.product_id)

LEFT JOIN product_to_store t3 ON(t1.product_id=t3.product_id)

..

LEFT JOIN product_attribute tn(t1.product_id=tn.product_id)

WHERE t1.product_id=9276

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
RGB    1 012
DELETE t1, t2, t3, ..., tn FROM product t1
LEFT JOIN product_to_category t2 ON(t1.product_id=t2.product_id)
LEFT JOIN product_to_store t3 ON(t1.product_id=t3.product_id)
..
LEFT JOIN product_attribute tn(t1.product_id=tn.product_id)
WHERE t1.product_id=9276

 

Спасибо, но разве можно так делать? Я имею в виду DELETE t1 FROM product t1  

sql ругается 

 

#1093 - You can't specify target table 't1' for update in FROM clause

 

Запрос ввожу такой:

DELETE t1, t2, ... t15 
FROM product t1
LEFT JOIN product_attribute t2 ON(t1.product_id=t2.product_id)
LEFT JOIN product_description t3 ON(t1.product_id=t3.product_id)
...
LEFT JOIN review t15 ON(t1.product_id=t15.product_id)
WHERE t1.product_id IN (SELECT t1.product_id FROM product t1 LEFT JOIN product_description t3 ON (t1.product_id = t3.product_id) LEFT JOIN manufacturer m ON (t1.manufacturer_id = m.manufacturer_id) LEFT JOIN product_to_category t11 ON (t1.product_id = t11.product_id) WHERE t11.category_id = '146' AND t1.manufacturer_id = '49')

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
freelancer    1 410

запрос полностью укажите, без троеточий

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
RGB    1 012

запрос полностью укажите, без троеточий

DELETE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15 FROM product t1
LEFT JOIN product_attribute t2 ON(t1.product_id=t2.product_id)
LEFT JOIN product_description t3 ON(t1.product_id=t3.product_id)
LEFT JOIN product_discount t4 ON(t1.product_id=t4.product_id)
LEFT JOIN product_image t5 ON(t1.product_id=t5.product_id)
LEFT JOIN product_option t6 ON(t1.product_id=t6.product_id)
LEFT JOIN product_option_value t7 ON(t1.product_id=t7.product_id)
LEFT JOIN product_related t8 ON(t1.product_id=t8.product_id)
LEFT JOIN product_reward t9 ON(t1.product_id=t9.product_id)
LEFT JOIN product_special t10 ON(t1.product_id=t10.product_id)
LEFT JOIN product_to_category t11 ON(t1.product_id=t11.product_id)
LEFT JOIN product_to_download t12 ON(t1.product_id=t12.product_id)
LEFT JOIN product_to_layout t13 ON(t1.product_id=t13.product_id)
LEFT JOIN product_to_store t14 ON(t1.product_id=t14.product_id)
LEFT JOIN review t15 ON(t1.product_id=t15.product_id)
WHERE t1.product_id IN (SELECT t1.product_id FROM product t1 LEFT JOIN product_description t3 ON (t1.product_id = t3.product_id) LEFT JOIN manufacturer m ON (t1.manufacturer_id = m.manufacturer_id) LEFT JOIN product_to_category t11 ON (t1.product_id = t11.product_id) WHERE t11.category_id = '146' AND t1.manufacturer_id = '49')

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
freelancer    1 410


DELETE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15

FROM product t1

LEFT JOIN product_attribute t2 ON(t1.product_id=t2.product_id)

LEFT JOIN product_description t3 ON(t1.product_id=t3.product_id)

LEFT JOIN product_discount t4 ON(t1.product_id=t4.product_id)

LEFT JOIN product_image t5 ON(t1.product_id=t5.product_id)

LEFT JOIN product_option t6 ON(t1.product_id=t6.product_id)

LEFT JOIN product_option_value t7 ON(t1.product_id=t7.product_id)

LEFT JOIN product_related t8 ON(t1.product_id=t8.product_id)

LEFT JOIN product_reward t9 ON(t1.product_id=t9.product_id)

LEFT JOIN product_special t10 ON(t1.product_id=t10.product_id)

LEFT JOIN product_to_category t11 ON(t1.product_id=t11.product_id)

LEFT JOIN product_to_download t12 ON(t1.product_id=t12.product_id)

LEFT JOIN product_to_layout t13 ON(t1.product_id=t13.product_id)

LEFT JOIN product_to_store t14 ON(t1.product_id=t14.product_id)

LEFT JOIN review t15 ON(t1.product_id=t15.product_id)

WHERE t11.category_id = '146' AND t1.manufacturer_id = '49'

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
RGB    1 012

Вот я тормоз  :-)  Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
freelancer    1 410

в фильтре товаров это же действие занимает пару кликов кстати. чем не удобно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
afwollis    1 097

Ушло в FAQ

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
RGB    1 012

в фильтре товаров это же действие занимает пару кликов кстати. чем не удобно?

Я стремлюсь к максимальной автоматизации :) Это если одна или несколько категорий и производителей, то все просто, но дилеры обычно работают с десятками брендов, которые к тому же представлены товарами в десятках или даже сотнях категорий. Например, после очередной ревизии списка дилеров я пометил на удаление штук 30 брендов из полутора сотен категорий - можно конечно посидеть пару часов в админке с фильтром и все почистить, но контент-менеджеры могут снова ошибочно добавить товары этих брендов (контролировать это сложно из-за большого ассортимента), тогда опять придется тоже самое делать.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти


  • Похожий контент

    • От RGB
      Всем привет, вопрос скорее к разработчикам, которые зарабатывают в нац. валюте и получают переводы в яндекс.деньгах например. Все видят какой сейчас курс, и ожидать серьезного улучшения ситуации наивно, поэтому интересно кто как спасает заработанное от обесценивания? Я сейчас вижу несколько путей, от действий "в лоб" - вывода денег в наличку и покупки доллара - до каких то более заумных схем с открытием валютного депозита или какой-то экзотики типа перевода части денег в WMZ или биткойны и т.д. Поделитесь пожалуйста опытом, кто как сейчас решает эту проблему и какой способ вы считаете выгоднее?
    • От RGB
      У меня вопрос к опытным разработчикам - надоело ставить костыли в шаблоны и решил приобщиться к таинствам разработки человеческих модулей для перенесения настроек шаблона в админку. Я взял болванку готового модуля, очистил ее от лишнего и получилось нечто, что имеет в настройках лишь переключатель yes/no, соответственно если выбран yes, то значение единственного свойства модуля (mymoduleproperty) равно 1. Потом я добавил в контроллер product.php такой кусок
      $this->data['mymodule_settings'] = $this->config->get('mymodule_settings'); if ($this->config->get('mymodule_mymoduleproperty')) { $this->data['mymoduleproperty'] = $this->config->get('mymodule_mymoduleproperty'); } else { $this->data['mymoduleproperty'] = false; } и смог в шаблоне вывести в нужном мне месте значение свойства, но это изменение базового контроллера, для чего нужен vqmod (а в некоторых шаблонах, которые я видел, авторы вообще без тени смущения перезаписывают контроллер header.php), а его использовать не хотелось бы. 
       
      Поэтому вопрос - как правильно это сделать БЕЗ vqmod и перезаписи, если мне модуль нужен лишь как место хранения и изменения настроек шаблона? 
    • От RGB
      Всем привет, недавно запустили на самых крупных тематических форумах баннерную рекламу с интересными большими скидками, и то ли лыжи не едут, то ли я переоцениваю количество людей, не знающих про адблок - выхлопа практически ноль, переходов совсем единицы, про заказы лучше вообще не говорить :) Либо это баннерная слепота развилась так сильно, я уж не знаю. У кого как с этим дела обстоят, пробовали ли нечто подобное и как это сработало?
    • От RGB
      Доброго! Реальная ситуация на работе - есть хорошие постоянные покупатели, которым иногда делаем скидку для более красивой суммы заказа, ну или как договоримся, например за все про все получилось 9132.48, а мы скидываем 132.48. Раньше учет заказов не велся в админке, но теперь я решил туда перевести все, и столкнулся с такой проблемой - итоговая сумма привязана к стоимости товаров, и не редактируется.
       
      Мне пришла в голову идея реализовать такие скидки в виде купонов на фиксированную сумму, т.е. на каждый такой заказ применять универсальный купон, в котором будет указана каждый раз разная сумма скидки, но вероятно есть способ или модуль удобнее? Может кому-то попадалось на глаза?
    • От RGB
      Тему можно удалить
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу