【问题标题】:SQL | Parent Child relationship in same tableSQL |同一张表中的父子关系
【发布时间】:2021-09-07 19:56:20
【问题描述】:

我有一个表在同一个表中有父子键关系,我需要找到没有任何子项的父行(例如第 1 行没有其他子项)和最近的子项(例如就像第 17 行有 3 个孩子,即 10,13,14,我们只需要获取最近的孩子,即 10)

【问题讨论】:

  • 未来:请提供可复制格式的示例(不是图像),最好是一些在线数据库引擎中的示例,例如this。你也应该标记你的 db-engine fe。 sql-servermysql
  • 对于 SQL 问题,重要的是包含您期望的输出示例,在这种情况下,不清楚结果是否应该在同一行中包含父项和子项,或者是否包含可接受将一起描述的两个查询的结果合并到一个结果集中但作为不同的行。
  • 0 放入parent_id 列以指示“无父”是一个错误的数据模型,因为这样您就不再能够定义适当的外键约束来确保您只参考现有的父母。您应该使用 null 而不是 0 以便您可以设置 FK 约束
  • 请提供足够的代码,以便其他人更好地理解或重现问题。

标签: postgresql


【解决方案1】:

你需要一个与主父母相关的部分:

SELECT parent.*
FROM MyTable AS parent
WHERE parent_id = 0

接下来您需要找到最近的直接子代:

SELECT parent.*, child.*
FROM MyTable AS parent
LEFT JOIN MyTable AS child
  ON child.parent_id = parent.id
WHERE parent_id = 0
AND RANK() OVER (PARTITION BY child.parent_id ORDER BY child.id DESC) = 1

并添加无子元素:

SELECT parent.*, child.*
FROM MyTable AS parent
LEFT JOIN MyTable AS child
  ON child.parent_id = parent.id
WHERE parent_id = 0
AND (
  RANK() OVER (PARTITION BY child.parent_id ORDER BY child.id DESC) = 1
  OR child.id IS NULL)

【讨论】:

    【解决方案2】:

    这样的事情应该可行,但可能不是最有效的方法:

    select {desired fields}
    from your_table
    where not exists
    (
       select 1 from your_table B
       where B.parent_id = your_table.id
    )
    UNION
    select {desired fields}
    from your_table
    where id in
    (
       select max(id)
       from your_table B
       where B.parent_id = your_table.id
    )
    

    【讨论】:

    • 请在您的回答中提供更多详细信息。正如目前所写的那样,很难理解您的解决方案。
    【解决方案3】:

    嗯。 . .你似乎想要每个父母一行。如果没有孩子,则可以是最近的孩子或父母。您实际上可以使用窗口函数来做到这一点:

    select t.*
    from (select t.*,
                 row_number() over (partition by coalesce(nullif(parent_id, 0), id
                                    order by parent_id desc, id desc
                                   ) as seqnum
          from t
         ) t
    where seqnum = 1;
    

    【讨论】:

      猜你喜欢
      • 2012-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-27
      • 1970-01-01
      相关资源
      最近更新 更多