【问题标题】:outer join for parent child chain父子链的外连接
【发布时间】:2023-03-17 13:35:02
【问题描述】:

考虑下表和关系:

父母 --1:Many-- 孩子 --1:Many-- 子孩子

  • 父母可能有或很多没有孩子 记录。
  • 子项总是有子项记录。

我想编写一个查询来选择匹配的父名称 parent.name、children.name 或 subchildren.name。

我知道我必须在父母和孩子之间进行左外连接。但是我应该在孩子和子孩子之间加入什么样的联接?

【问题讨论】:

  • 实际使用的数据库产品是什么,或者是加入试验的一部分? :)
  • 你可以 INNER JOIN 孩子和子孩子,看我的回答。

标签: sql outer-join


【解决方案1】:

如果我理解你的问题,这可行:

declare @theName char(25)
select @theName = 'dave'

SELECT p.id, p.name 
FROM parent p
LEFT OUTER JOIN child c   -- OUTER in case there's no children
    ON p.id = c.parentid
INNER JOIN grandchild g   -- INNER because you say there's always children
    ON c.id = g.parentid
WHERE p.name = @theName
    OR c.name = @theName
    OR g.name = @thename
GROUP BY p.id, p.name     -- GROUP BY to combine multiple hits

编辑(在被接受后)添加:我实际上也会使用OUTER 作为第二个JOIN,以防万一规则更改而没有警告。不需要也无妨。

【讨论】:

    【解决方案2】:

    如果孩子总是有子孩子,你应该使用 INNER JOIN

    【讨论】:

      【解决方案3】:

      此查询将返回所有父级(有或没有我们的子级),并在那些没有任何子级的父级的列中返回空值。

      SELECT  *
      FROM    Parent p LEFT JOIN
              Children c ON p.ID = c.ParentID LEFT JOIN
              SubChildren sc ON c.ID = sc.ChildID
      

      如果您要将 Children 和 SubChildren 之间的 JOIN 更改为 INNER

      SELECT  *
      FROM    Parent p LEFT JOIN
              Children c ON p.ID = c.ParentID INNER JOIN
              SubChildren sc ON c.ID = sc.ChildID
      

      那么你将不会从没有孩子的父母那里得到行。

      【讨论】:

        【解决方案4】:
        SELECT  p.*
        FROM    (
                SELECT  id
                FROM    parent
                WHERE   name = 'myname'
                UNION
                SELECT  parent_id
                FROM    child
                WHERE   name = 'myname'
                UNION
                SELECT  c.parent_id
                FROM    child c
                JOIN    grandchild gc
                ON      gc.parent_id = c.id
                WHERE   gc.name = 'myname'
                ) q
        JOIN    parent p
        ON      p.id = q.id
        

        【讨论】:

        • 您可以将第二个和第三个 SELECT 合并为一个。
        • 他说总有孙子,所以你可以INNER JOIN子孙。
        • @egrunin:是的,我可以。现在如何区分具有特定名称的子孙?
        • 他的问题模棱两可。我读它的意思是,“告诉我所有在他们的家谱中名字叫‘戴夫’的人”。如果这是正确的,那么即使后代中有多个“戴夫”,您也只需要一个父母。
        猜你喜欢
        • 1970-01-01
        • 2011-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-06
        • 2014-07-18
        • 2019-09-01
        相关资源
        最近更新 更多