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…)

すべての空のカテゴリ (製品が含まれていない) と、未公開の製品のみを含むカテゴリを検索したいと考えています。この 2 番目の部分は、私が立ち往生している場所です。

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にあるカテゴリが必要です.

4

3 に答える 3

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節は存在しない製品を最初のテストで一致させるか、未公開の製品を 2 番目のテストで一致させることができます。

于 2013-10-25T10:26:01.837 に答える
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.

EDIT: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 に答える