SQL — запрос, основанный на двух столбцах

#php #mysql #sql

Вопрос:

У меня довольно большая таблица продуктов, и мне нужно какое-то умное решение, чтобы выяснить, какие продукты (с точки зрения woocommerce) просты, изменчивы и разнообразны.

В приведенной ниже таблице примеров идентификаторы 6 и 7 являются простыми продуктами (у них нет детей), 1 и 4-Переменные продукты (у них есть дети), а 2,3,5-Вариации (они являются детьми).

ID item_id parent_id другие цвета
1 ааа ааа
2 ааа-1 ааа
3 ааа-2 ааа
4 ввв ввв
5 ввв-1 ввв
6 ссс ссс
7 ddd ddd

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

У меня есть решение для простых продуктов:

 SELECT *
FROM (
    SELECT *
    FROM $table_name
    WHERE item_id = parent_id
    GROUP BY parent_id
    HAVING COUNT(*) = 1
) AS ONLY_ONCE
 

Я пробовал аналогичное для переменных продуктов ( count(*) > 1 ), но это не работает…

Для разнообразия у меня есть:

 SELECT * 
FROM $table_name 
WHERE item_id != parent_id
 
  1. Простые продукты — выберите все, где item_id равен parent_id, а parent_id встречается только один раз.
  2. Переменные продукты — выберите все, где item_id равен parent_id и parent_id встречается более одного раза.
  3. Вариант — выберите все, где item_id и parent_id не равны.

Как я мог написать эти три запроса, особенно второй? любая помощь будет признательна.

Ответ №1:

 SELECT *,
       CASE WHEN EXISTS ( SELECT NULL
                          FROM test t2
                          WHERE t2.parent_id = t1.item_id
                            AND t2.item_id <> t2.parent_id )
            THEN 'Variable'
            WHEN NOT EXISTS ( SELECT NULL
                              FROM test t3
                              WHERE t3.parent_id = t1.item_id )
            THEN 'Variation'
            ELSE 'Simple'
            END Category
FROM test t1;
 

https://dbfiddle.uk/?rdbms=mysql_8.0amp;fiddle=b3215cbb3febbdbc4132ee00aac2ad8e

Комментарии:

1. Спасибо вам за ваш ответ! Этот код действительно работает, но он недостаточно эффективен, его обработка занимает слишком много времени (более 200 секунд), хотя я выбираю только три столбца. У меня есть таблица (~50 МБ) с 16 тысячами строк и 35 столбцами.

2. @Marin Создайте четыре индекса. Уникальные индексы по (item_id) , (item_id, parent_id) и (parent_id, item_id) , и индекс по (parent_id) . Проверьте скорость. Если они улучшатся, посмотрите на план выполнения запроса и удалите неиспользуемые индексы. Помните — если массив данных сильно меняется, то пакет оптимальных индексов может измениться.

Ответ №2:

Я бы решил это как комбинацию SQL-запросов и php-кода.

Сначала я получал всех родителей (переменные продукты) и получал результаты. В PHP затем просмотрите результаты и используйте идентификатор родителей в качестве параметра для следующего запроса.

Комментарии:

1. В этом нет никакого смысла. Обработка данных, которая может выполняться в СУБД, должна выполняться в СУБД.