Mysql 如何从两个表中查询相邻的层次结构数据,其中一行是类别,其余是该类别的内容?

Mysql 如何从两个表中查询相邻的层次结构数据,其中一行是类别,其余是该类别的内容?,mysql,sql,database,hierarchy,Mysql,Sql,Database,Hierarchy,免责声明:我是语言学家,不是计算机科学家。我熟悉编程,但我不是专家。这个项目是为一个濒危语言的大词典。我需要对大约1000个词素进行分类,这样我就可以直观地看到哪些词丢失了,哪些词可能被添加了 我在MySQL中有两个表 词汇表 类别表 lexicon表中的每个记录(行)都有一个父id值(pid),对应于categories表的id(我已将其重命名为文件夹) 我是根据邻接模型设计的(我需要灵活性来轻松更改树) 类别 | folder | name | pfolder | +----

免责声明:我是语言学家,不是计算机科学家。我熟悉编程,但我不是专家。这个项目是为一个濒危语言的大词典。我需要对大约1000个词素进行分类,这样我就可以直观地看到哪些词丢失了,哪些词可能被添加了


我在MySQL中有两个表

  • 词汇表
  • 类别表
  • lexicon表中的每个记录(行)都有一个父id值(pid),对应于categories表的id(我已将其重命名为文件夹)

    我是根据邻接模型设计的(我需要灵活性来轻松更改树)

    类别

    | folder |     name    | pfolder |
    +--------+-------------+---------+
    | 1      | Animals     | NULL    |
    | 2      | Wild        | 1       |
    | 3      | Domestic    | 1       |
    
    词汇

    | id     | pid   | word        | translation |
    +--------+-------+-------------+-------------+
    | 1      | 3     | Hund        | dog         |
    | 2      | 2     | Rentier     | reindeer    |
    | 3      |       | Maus        | Mouse       |
    

    目标

    | main    | main_content  |  sub1     | sub1_content | sub2      | sub2_content |
    +---------+---------------+-----------+--------------+-----------+--------------+
    | Animals | NULL          | Domestic  | Hund         | NULL      | NULL         |
    | Animals | NULL          | Wild      | Rentier      | NULL      | NULL         |
    | Animals | Maus          | NULL      | NULL         | NULL      | NULL         |
    
    示例查询

    我不知道如何做到这一点,我不能简单地遵循,因为我有多个表

    这个简单的查询不应该工作吗

    SELECT main.name  AS main
    FROM categories AS main
        LEFT JOIN hd FROM lexicon ON lexicon.pid = categories.main
    
    最终

    最后,我想列出一个很好的有组织的词汇表。在这里,我用粗体表示文件夹,用斜体表示列表项

    • 动物
      • 野生
        • 出租人
      • 国内
        • 匈奴
      • 毛斯

    此数据将使用Xeletex打印。为了简单起见,我尽量减少了上面的示例表。对词典表的实际查询将包括
    词素
    正交词
    ,和
    拼音词
    (在国际拼音字母表中)。

    这有点复杂,但我认为它满足了您的需要。一个很难的改变是,若你们想在动物下显示pid=1,你们需要把它放在词典的Maus行中

    SELECT
       COALESCE(c3.name, c2.name, c1.name) as main
      ,CASE WHEN (c3.name is null and c2.name is null) then lex.word end as main_content
      ,CASE WHEN (c3.name is null and c2.name is not null) then c1.name 
            WHEN (c3.name is not null and c2.name is not null) then c2.name end as sub1
      ,CASE WHEN (c3.name is null and c2.name is not null) then lex.word end as sub1_content
      ,CASE WHEN (c3.name is not null and c2.name is not null) then c1.name end as sub2
      ,CASE WHEN (c3.name is not null and c2.name is not null) then lex.word end as sub2_content
    FROM
      Lexicon lex
    LEFT JOIN 
      Categories c1 ON lex.pid = c1.folder
    LEFT JOIN
      Categories c2 on c1.pfolder = c2.folder
    LEFT JOIN
      Categories c3 on c2.pfolder = c3.folder
    

    -我还添加了一个子类别(Wild下的通配符),以测试SUB2是否正确?

    我不确定,但可能与2个Alliaes
    main
    发生冲突。您的查询似乎语法良好,但您将只获得
    名称
    列,而不是目标表中列出的6列列;如果您想知道您的查询是否有效,请尝试:-)@Marcassin当然我尝试过,但我应该提到它不起作用。关于别名,你可能是对的,但是,我不认为这是唯一的问题。正如示例查询中所述,“我不知道如何做”指的是目标表,您能解释一下“lex”是什么吗?我对你的出色工作投了赞成票@macmadness86“lex”是我给table Lexicon的一个别名,用来在使用时缩短它(lex.Word而不是Lexicon.Word)。您总是可以这样做,以使您的查询更易于编写,或者在类似c1、c2、c3(还有别名)的情况下,您必须这样做,以便在同一个表上的不同联接之间产生差异。