代码之家  ›  专栏  ›  技术社区  ›  Stephane Grenier

如何在SQL中实现“hasschildren”select语句?

  •  4
  • Stephane Grenier  · 技术社区  · 15 年前

    假设我有下表:

    ID | parentID | MoreStuff
    1  | -1       |  ...
    2  |  1       |  ...
    3  |  1       |  ...
    4  |  2       |  ...
    5  |  1       |  ...
    

    如何生成SQL Select语句以确定特定行是否有子行?换句话说,我想知道ID 1是否有子代,在本例中它有3个。

    我不知道如何创建SQL语句:

    SELECT ID, hasChildren FROM myTable;
    

    在上面的SQL select语句中,将为hasschildren替换什么?

    5 回复  |  直到 15 年前
        1
  •  16
  •   Alex Bagnolini    15 年前

    无组版本:

    SELECT MyTable.Id, CASE WHEN EXISTS 
        (SELECT TOP 1 1  --you can actually select anything you want here
         FROM MyTable MyTableCheck 
         WHERE MyTableCheck.ParentId = MyTable.Id
        ) THEN 1 ELSE 0 END AS HasRows
    FROM MyTable
    
        2
  •  12
  •   Andomar    15 年前

    单独联接表以查找是否有子表:

    SELECT 
        parent.id as ID
    ,   case when count(child.id) > 0 then 1 else 0 end as hasChildren 
    FROM       myTable parent
    LEFT JOIN  myTable child
    ON         child.parentID = parent.ID
    GROUP BY   parent.id
    
        3
  •  2
  •   Kaleb Brasee    15 年前

    如果您已经知道父ID,那么查询很简单——只需选择具有该父ID的行数。

    SELECT count(*) FROM myTable where parentID = 1;
    
        4
  •  2
  •   GateKiller    15 年前

    对你的问题有非常有效的答案,这是可行的。但是,如果您的数据集非常大,我将考虑这种查询的性能。

    如果要使用GroupBy或Sub查询获取数据,请确保ID列和父列都有单独的索引。

    为了获得更好的性能,您应该添加一个名为“hasschildren”的列,该列可以是“bit”数据类型。然后,在插入或删除项目时,应根据应用程序代码更新此列。这将允许您运行更快的查询:

    SELECT * FROM table WHERE haschildren IS NOT NULL
    
        5
  •  1
  •   FelixM    15 年前

    上面的解决方案是好的,但是你不应该添加像“hasschildren”这样的列,除非你真的有性能问题(见gatekiller的帖子)。这样的列会使数据库非规范化,即同一条信息将存储在两个位置,这使得您的数据更有可能变得不一致。每当插入新的子级、删除现有的子级或更新子级的父级时,都必须维护此列。