以下是我想要执行的SQL。我想避免做多次请求,我很确定这是可能的......
First table : products_categories (category_id, category_infos…)
Second table : products_categories_relations (product_id, category_id)
Third table : products (product_id, published, products_infos…)
我想查找所有空类别(其中没有产品)和仅包含未发布产品的类别。第二部分是我被困的地方。
SELECT pc.`category_id`
FROM `#__products_categories` AS pc
LEFT JOIN `#__products_categories_relations` pcr
ON pc.`category_id` = pcr.`category_id`
WHERE pcr.`category_id` IS NULL
此查询为我提供了没有产品的类别,但我无法看到如何插入条件说:
“对于每个带有产品的类别,返回仅包含已公布的产品= 0”的
我的分析是:
如果A是查询“没有产品的类别”的结果
和B是“仅有未发布产品的类别”的结果
我需要A或B中的类别。
答案 0 :(得分:0)
SELECT pc.*
FROM products_categories pc
INNER JOIN products_categories_relations pcr
ON (pc.category_id = pcr.category_id)
INNER JOIN products p
ON (pcr.product_id = p.product_id AND published = 0)
EXCEPT
SELECT pc.*
FROM products_categories pc
INNER JOIN products_categories_relations pcr
ON (pc.category_id = pcr.category_id)
INNER JOIN products p
ON (pcr.product_id = p.product_id AND published != 0)
基本上,您查询具有已发布= 0的产品的类别,并从集合中删除所有已发布非0的产品。这将完全满足您的需求。
请注意,已发布= 0的产品的类别与空类别不同。如果您还需要空类别,只需制作union all
。
编辑: 正如我刚才提醒的那样,MySQL 仍然没有一些基本的SQL操作可以解决这个问题:
SELECT pc.*
FROM products_categories pc
INNER JOIN products_categories_relations pcr
ON (pc.category_id = pcr.category_id)
INNER JOIN products p
ON (pcr.product_id = p.product_id AND published = 0)
WHERE pc.product_category_id NOT IN
(
SELECT distinct pc.product_category_id
FROM products_categories pc
INNER JOIN products_categories_relations pcr
ON (pc.category_id = pcr.category_id)
INNER JOIN products p
ON (pcr.product_id = p.product_id AND published != 0)
)
或者你也可以做到:
SELECT * FROM
(
SELECT distinct pc.*
FROM products_categories pc
INNER JOIN products_categories_relations pcr
ON (pc.category_id = pcr.category_id)
INNER JOIN products p
ON (pcr.product_id = p.product_id AND published = 0)
) subQ1
LEFT OUTER JOIN
(
SELECT distinct pc.*
FROM products_categories pc
INNER JOIN products_categories_relations pcr
ON (pc.category_id = pcr.category_id)
INNER JOIN products p
ON (pcr.product_id = p.product_id AND published != 0)
) subQ2
ON subQ1.product_category_id = subQ2.product_category_id
WHERE subQ2.product_category_id IS NULL
我怀疑第一个应该更快,但你可以尝试两者。
答案 1 :(得分:0)
UNION可能会帮到你:
SELECT pc.`category_id`
FROM `#__products_categories` AS pc
LEFT JOIN `#__products_categories_relations` pcr
ON pc.`category_id` = pcr.`category_id`
WHERE pcr.`category_id` IS NULL
union
select category_id
from
(
SELECT pc.`category_id`,
sum(case when p.`published`=0 then 1 else 0 end) as unpublishedProductsCount,
count(*) as allProductsCount
FROM `#__products_categories` AS pc
INNER JOIN `#__products_categories_relations` pcr
ON pc.`category_id` = pcr.`category_id`
INNER JOIN `#__products` p on p.product_id = pcr.product_id
GROUP BY pc.`category_id`
) t
where t.allProductsCount = t.unpublishedProductsCount
;
union
上方的上半部分是查询空类别的查询。
union
下方的下半部分是一个查询,用于查找仅包含published=0
答案 2 :(得分:0)
SELECT pc.`category_id`
FROM `#__products_categories` AS pc
LEFT JOIN `#__products_categories_relations` pcr
ON pc.`category_id` = pcr.`category_id`
LEFT JOIN (SELECT product_id, MAX(published) published
FROM products
GROUP BY product_id
HAVING published = 0) p
ON pcr.product_id = p.product_id
WHERE pcr.`category_id` IS NULL OR p.product_id IS NOT NULL
子查询查找所有未发布的产品。我们加入,然后WHERE
子句可以匹配不存在的产品与第一个测试,或未发布的产品与第二个测试匹配。