【问题标题】:Determine if a record is a descendant of another record using recursive CTE使用递归 CTE 确定一条记录是否是另一条记录的后代
【发布时间】:2018-09-01 03:53:18
【问题描述】:

下表存储了说明手册中的主题。每个主题都有一个父主题,但记录 id1 是根主题。该应用程序允许除根主题之外的所有主题更改父主题,并且我需要防止将祖先分配为自身的后代。

例如,记录#2 的父级不应从1 更改为7

如何确定一条记录是否是另一条记录的后代?我宁愿不要“硬编码”后代的数量。请注意,我实际上使用的是 mariaDB。

CREATE TABLE IF NOT EXISTS `app`.`manual` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL,
  `content` TEXT NULL,
  `listorder` TINYINT NULL,
  `keywords` TEXT NULL,
  `display_list` TINYINT NULL,
  `parent_id` INT NULL,
  PRIMARY KEY (`id`),
  INDEX `fk_manual_manual1_idx` (`parent_id` ASC),
  CONSTRAINT `fk_manual_manual1`
    FOREIGN KEY (`parent_id`)
    REFERENCES `app`.`manual` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

id   parent_id
1    null
2    1
3    2
4    3
5    4
6    5
7    6

【问题讨论】:

  • 这可能是一个很难用递归解决的问题。更经济的答案可能path 专栏
  • @PhilippMaurer 是的,有答案,但它们似乎都使用存储过程。递归不是更好的解决方案吗?
  • @user1032531 在普通 SQL 中递归很困难。
  • @Barmar 也许是这样,但这似乎是一个相当普遍的应用程序,几乎没有偏差,我希望其他人会在 Stackoverflow 上找到这样的答案。

标签: mariadb common-table-expression hierarchical-data recursive-query


【解决方案1】:

如果id 为 6 的记录是id 为 2 的记录的后继,则以下查询将返回大于零的计数。

WITH RECURSIVE ancestors AS (
SELECT * FROM manual WHERE id=2
UNION
SELECT m.*
FROM manual m
INNER JOIN ancestors a ON a.id=m.parent_id
)
SELECT COUNT(*) FROM ancestors WHERE id=6;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2014-02-02
    • 2020-05-10
    • 2019-09-30
    • 2012-07-27
    相关资源
    最近更新 更多