Поиск идентификаторов продуктов, где атрибут отсутствует - PullRequest
0 голосов
/ 09 февраля 2019

Я использую opencart для интернет-магазина, и у меня есть такая структура SQL: data (изображение из phpmyadmin)

Я пытаюсь сопоставить идентификаторы продуктов с идентификаторами атрибутов.Мне нужно найти продукты, у которых нет определенного attribute_id (attribute_id 17, если быть более точным).

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

Также попытался использовать этот код:

SELECT product_id FROM oc_product_attribute WHERE NOT EXISTS (SELECT * FROM oc_product_attribute WHERE attribute_id = 17) (имя таблицы - oc_product_attribute)

... но он не дал никаких результатов.

Пожалуйста, помогите мне понять, как я могу найти идентификаторы продукта, которые не имеют идентификатора атрибута 17.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

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

Существует два распространенных способа достижения вашей цели.Один использует LEFT JOIN:

select p.*
from oc_product p
left join oc_product_attribute a
  on  a.product_id = p.product_id
  and a.attribute_id = 17
where a.product_id is null

Важно, чтобы условие a.attribute_id = 17 было в условии ON.Если вы используете его в предложении WHERE, LEFT JOIN будет преобразован в INNER JOIN, и вы получите пустой результат.

Другой способ - использовать связанный подзапрос NOT EXISTS:

select p.*
from oc_product p
where not exists (
    select *
    from oc_product_attribute a
    where a.product_id = p.product_id
      and a.attribute_id = 17
)

Обратите внимание на условие (корреляции) a.product_id = p.product_id.Если вы пропустите это (как в вашей попытке), подзапрос всегда найдет строку, а NOT EXISTS всегда вернет FALSE.

Оба подхода имеют одинаковую производительность.

Если вам нужен только продуктидентификаторы, которые вы можете заменить p.* на p.product_id.

0 голосов
/ 09 февраля 2019

Ваш текущий подход находится на правильном пути, но вам необходимо соотнести существующий подзапрос с внешним запросом:

SELECT DISTINCT o1.product_id
FROM oc_product_attribute o1
WHERE NOT EXISTS (SELECT 1 FROM oc_product_attribute o2
                  WHERE o1.product_id = o2.product_id AND o2.attribute_id = 17);

Мы также могли бы использовать здесь метод агрегирования:

SELECT product_id
FROM oc_product_attribute
GROUP BY product_id
HAVING COUNT(attribute_id = 17) = 0;
...