【问题标题】:Mysql Query Incorporating Self Referential Join包含自引用连接的 Mysql 查询
【发布时间】:2010-08-16 11:27:51
【问题描述】:

假设我有四张桌子:

------------- features --------------
id: int
name: varchar
-------------------------------------

-------- feature_categories ---------
feature_id: int
category_id: int    
-------------------------------------

----------- categories --------------
id: int
name: varchar    
-------------------------------------

------ category_subcategories -------
category_id: int
sub_category_id: int    
-------------------------------------

类别有很多(子)类别,通过自引用连接子类别

一个特征有很多类别,其中一些是子类别,通过加入 feature_categories

我需要的是发送一组特征 ID 和一个(主)类别 ID,并返回所有子类别。事实证明,这比我希望的要困难得多,所以我非常感谢任何帮助。如果这个问题不清楚,请告诉我。

编辑 我不需要将特征表包含在任何查询中。在方面,我只需要返回子类别(类别)名称字段。

【问题讨论】:

  • 你的类别树只有深度 1 吗?即一个主要类别可以有子类别,但那些不能有自己的任何子类别?另外 - 除了 mysql,您是否使用任何编程语言或平台?
  • 嗨,Yoni。类别的深度仅为 1。我正在使用 ruby​​ on rails。
  • 只是为了澄清您的问题:您传递了功能 ID 和类别 ID,并且您想要返回所有子类别 - 其中包含任何传递的功能 ID 并且是您提供的类别的父类别 - 是对吗?
  • 嗨尼古拉斯。是的,有一个功能 ID。返回的类别必须是所提供类别的子类别。

标签: mysql join self-reference


【解决方案1】:

不得不解决这个问题,但下面的任何一个都应该工作。第二个可能更有效:

 select f.name featureName, 
  c.name CategoryName, 
  c2.name SubCategoryName  
    FROM features f, feature_categories fc, categories c, category_subcategories sc, categories c2, feature_categories fc2
    WHERE f.id = fc.feature_id
    AND c.id = fc.category_id
    AND sc.category_id = c.id
    and c2.id = sc.sub_category_id
    and fc2.category_id = c2.id
    AND f.id in (0,1,2,...)
    and fc2.feature_id in (0,1,2,...)
    AND c.id = @main_category_id

或:

    select f.name featureName, 
  c.name CategoryName, 
  c2.name SubCategoryName  
        FROM features f 
        inner join feature_categories fc on f.id = fc.feature_id
        inner join categories c on c.id = fc.category_id
        inner join category_subcategories sc on sc.category_id = c.id
        inner join categories c2 on c2.id = sc.sub_category_id
        inner join feature_categories fc2 on fc.category_id = c2.id

        WHERE f.id in (0,1,2,...)
        AND c.id = @main_category_id

        and fc2.feature_id in (0,1,2,...)

【讨论】:

  • 这是其中一个丑陋的连接。
  • 谢谢拉斯!第一个解决方案有效,但第二个无效。我删除了不需要的特征连接,并引用了 feature_categories.feature_id 以稍微简化查询。我将暂时保持开放状态,看看是否可以做出任何改进。再次感谢。
【解决方案2】:

以下是否可以完成这项工作?

SELECT *
FROM `category_subcategories` sc
  JOIN `categories` c ON sc.category_id = c.id
  JOIN `feature_categories` fc ON fc.category_id = c.id
WHERE fc.feature_id IN (0,1,2,...)
  AND c.id = main_category_id;

【讨论】:

  • 您好,感谢您的回答。恐怕这不会返回子类别。
  • 这看起来很接近,但是加入的类别的名称是父类别。
【解决方案3】:
select f.name featureName,
  c.name CategoryName,
  sc.name SubCategoryName 
from features f
join features_categories fc on f.id=fc.feature_id
join categories c on fc.category_id=c.id
join category_subcategories cs on c.id=cs.category_id
join categories sc on cs.sub_categories_id=sc.id
WHERE f.id IN (0,1,2,...)

如果我理解正确你在问什么......

【讨论】:

  • 嗨,乔,感谢您的回答。这可以根据需要使用附加的 main_category id 传递:“and c.id = @main_category_id”。我要去测试它,看看是否有人提出另一个答案。这看起来不错,但 sql 不是我的强项。
  • 好的,实际上这不适用于我的修改。将返回所有子类别,无论它们是否连接到某个要素。
  • 在这种情况下,我不太明白您需要什么。对于 (1,2,...) 中的特征,您需要与它们链接的所有子类别具有特定类别。您是否检查了所有组合的功能是否具有所有子类别(我不知道您是否正确理解了这个问题......)?如果您只尝试一项功能?在这种情况下,它会返回正确的子类别吗?
  • 嗨乔。它正确返回特征集合或单个特征的子类别,现在的问题是按主类别过滤这些子类别。
  • 马克,条件“and c.id = @main_category_id”不起作用?我仍然认为这是我在这里缺少的东西......
【解决方案4】:
select f.name featureName, 
c.name CategoryName, 
c2.name SubCategoryName  
FROM features f 
inner join feature_categories fc on f.id = fc.feature_id
inner join categories c on c.id = fc.category_id
inner join category_subcategories sc on sc.category_id = c.id
inner join categories c2 on c2.id = sc.sub_category_id
inner join feature_categories fc2 on fc.category_id = c2.id and fc2.feature_id = fc.feature_id
WHERE f.id in (0,1,2,...)
AND c.id = @main_category_id;

【讨论】:

    【解决方案5】:

    这可能会产生预期的结果

    select cat.name
      from categories cat,
           feature_categories feacat,
           category_subcategories cat_subcat
     where feacat.feature_id in (1,2,3)
       and feacat.category_id = cat.id
       and exists(select 1 
                    from cat_subcat 
                   where category_id = @catid 
                     and sub_category_id=cat.id
                 )
    

    【讨论】:

      猜你喜欢
      • 2011-12-03
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 2023-01-03
      • 1970-01-01
      相关资源
      最近更新 更多