SQL 如何获取不包含产品的类别?

Posted

技术标签:

【中文标题】SQL 如何获取不包含产品的类别?【英文标题】:SQL How to get categories that don't contain products? 【发布时间】:2019-03-03 08:05:46 【问题描述】:
SELECT DISTINCT c2.name 
FROM 
    BrandCategory AS c  
    JOIN CategoryProductRelation AS c2p  
    ON  c.pk = c2p.source  
    JOIN Product AS p  
    ON  c2p.target = p.pk  
    JOIN CategoryProductRelation AS c2p2  
    ON  p.pk = c2p2.target  
    JOIN TaxonomyCategory AS c2 ON c2.pk = c2p2.source 
    JOIN CatalogVersion AS cat 
    ON c.catalogVersion = cat.PK 
WHERE 
    c.code = 'brand-MCH' 
    ANDcat.version = 'Online' 
    AND c2.code NOT LIKE'%webFamily%' 
    AND p.code IN ('35365','34299')

上面的查询提取出包含产品“35365”和“34299”的分类分类

Result:
Passenger
Touring
All-Season
Truck

All Categories:
All-Season
Performance
Passenger
Winter
Touring
Summer
Truck
All-Terrain
Competition
Lawn

现在的要求是提取所有其他分类类别,即那些不包含产品“35365”和“34299”的类别

尝试 1:(失败)(未成功)

SELECT  DISTINCT c2.name
    FROM  BrandCategory AS c
    JOIN  CategoryProductRelation AS c2p  ON c.pk = c2p.source
    JOIN  Product AS p  ON c2p.target = p.pk
    JOIN  CategoryProductRelation AS c2p2  ON p.pk = c2p2.target
    JOIN  TaxonomyCategory AS c2  ON c2.pk = c2p2.source
    JOIN  CatalogVersion AS cat  ON c.catalogVersion = cat.PK
    WHERE  c.code = 'brand-MCH' ANDcat.version = 'Online'
      AND  c2.code NOT LIKE'%webFamily%'
      AND  p.code NOT IN ('35365','34299') 

尝试 2:(失败)(不存在)

SELECT  DISTINCT c2.name
    FROM  BrandCategory AS c
    JOIN  CategoryProductRelation AS c2p  ON c.pk = c2p.source
    JOIN  Product AS p  ON c2p.target = p.pk
    JOIN  CategoryProductRelation AS c2p2  ON p.pk = c2p2.target
    JOIN  TaxonomyCategory AS c2  ON c2.pk = c2p2.source
    JOIN  CatalogVersion AS cat  ON c.catalogVersion = cat.PK
    WHERE  c.code = 'brand-MCH' ANDcat.version = 'Online'
      AND  c2.code NOT LIKE'%webFamily%'
      AND  c2.code
      AND  NOT EXISTS (
        SELECT  DISTINCT c3.name
            FROM  BrandCategory AS c
            JOIN  CategoryProductRelation AS c2p  ON c.pk = c2p.source
            JOIN  Product AS p  ON c2p.target = p.pk
            JOIN  CategoryProductRelation AS c2p2  ON p.pk = c2p2.target
            JOIN  TaxonomyCategory AS c3  ON c3.pk = c2p2.source
            JOIN  CatalogVersion AS cat  ON c.catalogVersion = cat.PK
            WHERE  c3.name=c2.name
              AND  c.code = 'brand-MCH' ANDcat.version = 'Online'
              AND  c3.code NOT LIKE'%webFamily%'
              AND  p.code IN ('35365','34299')
                      ) 

尝试 3:(失败)(不在子查询中)

SELECT  DISTINCT c2.name
    FROM  BrandCategory AS c
    JOIN  CategoryProductRelation AS c2p  ON c.pk = c2p.source
    JOIN  Product AS p  ON c2p.target = p.pk
    JOIN  CategoryProductRelation AS c2p2  ON p.pk = c2p2.target
    JOIN  TaxonomyCategory AS c2  ON c2.pk = c2p2.source
    JOIN  CatalogVersion AS cat  ON c.catalogVersion = cat.PK
    WHERE  c.code = 'brand-MCH' ANDcat.version = 'Online'
      AND  c2.code NOT LIKE'%webFamily%'
      AND  c2.name NOT IN (
        SELECT  DISTINCT c2.name
            FROM  BrandCategory AS c
            JOIN  CategoryProductRelation AS c2p  ON c.pk = c2p.source
            JOIN  Product AS p  ON c2p.target = p.pk
            JOIN  CategoryProductRelation AS c2p2  ON p.pk = c2p2.target
            JOIN  TaxonomyCategory AS c2  ON c2.pk = c2p2.source
            JOIN  CatalogVersion AS cat  ON c.catalogVersion = cat.PK
            WHERE  c.code = 'brand-MCH' ANDcat.version = 'Online'
              AND  c2.code NOT LIKE'%webFamily%'
              AND  p.code IN ('35365','34299')
                          ) 

...

Result:
All-Season
Performance
Passenger
Winter
Touring
Summer
Truck
All-Terrain
Competition
Lawn

Expected:
Performance
Winter
Summer
All-Terrain
Competition
Lawn

请帮助获取那些不包含的类别,并通过最佳查询来控制性能。

此外,如果有一种方法可以让所有类别在结果中带有一些标志来区分哪些产品包含真实与否,那将是绝对的黄金,因为在这里我们点击 DB 两次以获取包含的类别,然后获取包含的类别不通过按需调用包含

注意:这些本质上是 SQL 查询,只是稍微修改了这些大括号以支持 Hybris 框架中的灵活搜索查询格式

【问题讨论】:

首先站点一个包含和一个不包含看起来像给我所有。您可以通过以文本形式提供示例数据和预期输出来改进此问题。 ***.com/questions/5748620/sql-server-not-in 您应该尝试将整个第一个查询放在“not in”子句中。 SELECT DISTINCT name FROM CategoryProductRelation where name not in(您的第一个查询) 请格式化您的代码,使其不会全部在一行中。 谢谢@Tuckbros 现在我有两个版本的查询,一个与 NOT IN 一起工作,一个与 NOT EXISTS 一起工作。 NOT EXISTS 的性能效率更高,但由于它是同一张表,我们不需要是吗? 【参考方案1】:

查询- 1. 使用 NOT IN-SELECT c.code FROM Product as p join CategoryProductRelation as c2p on c2p.target = p.pk join Category as c on c2p.source = c.pk WHERE p.code NOT IN ('35365','34299')

    使用不存在-SELECT c.code FROM CategoryProductRelation as c2p join Category as c on c2p.source = c.pk WHERE NOT EXISTS (SELECT p.code FROM Product as p WHERE p.code IN ('35365','34299') and c2p.target=p.pk)

    使用子查询-SELECT c.code FROM Product as p join CategoryProductRelation as c2p on c2p.target = p.pk join Category as c on c2p.source = c.pk WHERE p.pk IN (SELECT pk FROM Product WHERE code IN ('35365','34299'))

【讨论】:

【参考方案2】:

首先查看NOT EXISTSNOT IN 是否给出了正确的值。

对于EXISTS,不要打扰DISTINCT,也不要指定列。这足够了:

NOT EXISTS ( SELECT 1 FROM ... )

删除所有与问题无关的JOIN。这样可以更轻松地查看问题所在。

什么是大括号?也许您应该删除[mysql] 标签?

【讨论】:

以上是关于SQL 如何获取不包含产品的类别?的主要内容,如果未能解决你的问题,请参考以下文章

如何在sql中找到客户明智类别中的最大产品ID?

如何在 Pig 中动态获取组内的前 N% 记录

如何获取供应商产品所属的所有产品类别

CakePHP 我将如何获取类别明智的产品?

如何从 WooCommerce 中的订单项中获取产品类别 ID

如何获得所有亚马逊类别的产品