Sql server 如果任何子级或子级具有值,则选择SQL

Sql server 如果任何子级或子级具有值,则选择SQL,sql-server,sql-server-2012,Sql Server,Sql Server 2012,我有两个表,类别和文章。文章有一个FK,将其与一个类别关联。类别表是分层的,因此每个类别都有一个指向另一个类别的CAT_FK_父级,如果它是顶级类别,则为NULL 我试图做的是按类别对文章进行排序,并且只显示列表中与文章直接关联的类别,或与文章关联的子/子孩子的类别 所以现在我的代码看起来像: SELECT TOP 1000 [CAT_PK] ,[CAT_Description] ,[CAT_FK_Parent] ,[CAT_CanHaveChildren] ,[CAT_EMP

我有两个表,类别和文章。文章有一个FK,将其与一个类别关联。类别表是分层的,因此每个类别都有一个指向另一个类别的CAT_FK_父级,如果它是顶级类别,则为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条件的资源。

您应该使用联接来完成这项工作,而不是子查询,速度要快得多

  • 先加入文章
  • 然后加入包含文章的子类别
  • 然后检查是否存在一个连接到项目的连接(不为null)
  • 最后,通过分组或区分来删除重复行


您的意思是“或具有关联文章的子/子子子类的类别”。这目前运行良好,但它仅在子类中向下一层,因此,如果子类具有文章,则不会拾取该子类,因此是递归函数。如果您需要sql中的树层次结构,则递归是实现它的一种不好的方法。。。如果你的数据库有任何大小,它会变得非常缓慢。SQL Server通过特殊的数据类型支持这一点。
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