【问题标题】:SQL Select if any child or subchild has a valueSQL 选择是否有任何子或子子有值
【发布时间】:2015-11-20 01:16:57
【问题描述】:

我有两个表,类别和文章。文章具有将它们与类别相关联的 FK。 Category 表是分层的,因此每个类别都有一个指向另一个 Category 的 CAT_FK_Parent,如果它是顶级类别,则为 NULL。

我要做的是按类别对文章进行排序,并仅显示列表中与文章直接关联的类别,或具有关联文章的子/子子项的类别。

所以现在我的代码看起来像:

SELECT  TOP 1000 [CAT_PK]
  ,[CAT_Description]
  ,[CAT_FK_Parent]
  ,[CAT_CanHaveChildren]
  ,[CAT_EMP_FK]
  ,[CAT_Action]
  ,[CAT_Active]
  ,[CAT_Autoclose]
  ,[CAT_ROL_Name]
FROM [TicketCategories]
WHERE 
((SELECT COUNT(1) FROM WikiArticles WHERE WAR_CAT_FK = CAT_PK AND WAR_Active=1) ) > 0

这将返回 WAR_CAT_FK 与它们自己相同的类别,但不考虑孩子。

由于类别下可以有任意数量的子级别,我假设我需要某种递归函数来计算所有子级,但我在为递归 WHERE 条件查找资源时遇到了麻烦。

【问题讨论】:

  • 您的意思是“或具有关联文章的子/子的类别。”

标签: sql-server sql-server-2012


【解决方案1】:

您应该使用联接而不是子查询来执行此操作,速度要快得多。

  • 先加入文章
  • 然后加入有文章的儿童类别
  • 然后检查是否存在与文章的连接之一(不为空)
  • 最后通过 Group By 或 DISTINCT 删除重复行

.

SELECT DISTINCT TOP 1000
   TC.CAT_PK
  ,TC.CAT_Description
  ,TC.CAT_FK_Parent
  ,TC.CAT_CanHaveChildren
  ,TC.CAT_EMP_FK
  ,TC.CAT_Action
  ,TC.CAT_Active
  ,TC.CAT_Autoclose
  ,TC.CAT_ROL_Name
FROM TicketCategories TC
LEFT JOIN WikiArticles WA ON TC.WAR_CAT_FK = WA.CAT_PK AND WA.WAR_Active=1
LEFT JOIN TicketCategories Child ON TC.CAT_PK = Child.CAT_FK_Parent
LEFT JOIN WikiArticles CWA ON Child.WAR_CAT_FK = CWA.CAT_PK AND CWA.WAR_Active=1
WHERE 
  COALESCE(WA.CAT_PK,CWA.CAT_PK) IS NOT NULL

【讨论】:

  • 这个现在很好用,但它只在孩子中下降一层,所以如果孩子有一个孩子有一篇文章,它不会被捡起,因此是递归函数。跨度>
  • 如果您需要在 sql 中使用树层次结构,那么递归是一种不好的实现方式……如果您的 db 有任何大小,它将变得非常非常慢。 SQL Server 支持这种特殊数据类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
相关资源
最近更新 更多