1

下面是我要执行的 SQL。我想避免为此做多个请求,我很确定这是可能的……</p>

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 OR B 中的类别。

4

3 回答 3

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

我怀疑第一个应该更快,但你可以尝试两者。

于 2013-10-25T10:13:58.443 回答
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

于 2013-10-25T10:15:53.717 回答
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子句可以将不存在的产品与第一个测试匹配,或者将未发布的产品与第二个测试匹配。

于 2013-10-25T10:26:01.837 回答