【问题标题】:sql get a tree from hierarchical tablessql 从分层表中获取树
【发布时间】:2017-12-20 05:29:43
【问题描述】:

如果您有表的层次结构,表中的每个项目都包含对其父表中其父表的 id 的引用,有没有办法从单个(少数)sql 查询中获取该树作为树?

  • 物种(id、名称、属)
  • 属(id、name、family)
  • 家庭(身份证、姓名)

看起来像:

SELECT *
FROM specy
JOIN genus ON genus.id=specy.genus
JOIN family ON genus.family=family.id

但即使这在语法上是正确的,它是否不会返回一个数据集,其中包含该科的每个属的科字段,以及该属的每个物种的科和属字段?

SQL 可以直接(轻松地)返回一个层次树,还是只返回一个我必须用另一种语言处理的数据集?

【问题讨论】:

    标签: sql


    【解决方案1】:

    是的,SQL 可以使用common table expressions (CTEs) 返回分层数据,但并非所有数据库都支持 CTE。语法是:

    WITH [RECURSIVE] with_query [, ...]
    SELECT...
    

    例子:

    WITH RECURSIVE table1 (n, fact) AS 
    (SELECT col1+1, col1*col2 FROM table1)
    SELECT * FROM table1;
    

    【讨论】:

    • MariaDB -- MySQL 克隆 -- 10.2+ 可以做 CTE。
    【解决方案2】:

    如果您不想看到多余的信息,您可以按科和属对结果进行排序,然后使用用户变量将前一行中的重复项替换为空白。然后,您只会在更改时看到科和属名称。

    SELECT CASE WHEN f.id = @prev_family THEN '' ELSE f.name END AS family,
           CASE WHEN g.id = @prev_genus THEN '' ELSE g.name END AS genus,
           s.name AS species
    FROM specy AS s
    JOIN genus AS g ON s.genus = g.id
    JOIN family AS f ON g.family = f.id
    CROSS JOIN (SELECT @prev_family := 0, @prev_genus := 0) AS vars
    ORDER BY f.id, g.id, s.id
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 2011-05-22
      • 2013-01-11
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      • 1970-01-01
      相关资源
      最近更新 更多