MySQL树结构

MySQL树结构,mysql,sql,left-join,case,greatest-n-per-group,Mysql,Sql,Left Join,Case,Greatest N Per Group,您好,我正在尝试用MySql准备树结构,表看起来像这样 |id |parent_id | |entry_id| name |lang | |-----|----------| |--------|-------|------| | 1 | 0 | | 1| ABC | eng | | 2 | 1 | |

您好,我正在尝试用MySql准备树结构,表看起来像这样

 |id   |parent_id |               |entry_id| name  |lang  |
 |-----|----------|               |--------|-------|------|
 |   1 |    0     |               |       1| ABC   | eng  |
 |   2 |    1     |               |       1| BCD   | fra  |
 |   3 |    2     |               |       2| EFG   | eng  |
 |   4 |    2     |               |       2| HIJ   | fra  |
 |   5 |    2     |               |       3| WYX   | eng  |
我的问题是:

  • 是否可以按名称对列进行左连接和排序,但如果in lang是eq to“fra”,则返回具有该名称的行,否则返回“eng”名称
  • 伪码

    SELECT id, name FROM table LEFT JOIN table2 ON id = entity_id 
    WHERE (IF lang = 'fra' return french name otherwise return just english name) GROUP BY entry_id ORDER BY name ASC
    
    所以最终结果是这样的,总的来说,“fra”lang有优先权,所有结果都应该按名称排序

            |      id| name  |lang  |
            |--------|-------|------|
            |       1| BCD   | fra  |
            |       2| HIG   | fra  |
            |       3| WYX   | eng  |
    

    如果将table2拆分为两个表,一个只包含英语条目,另一个只包含法语条目,并将它们与id上的条目合并,则每个id将有一个单独的行,其中包含告诉使用哪种语言名称所需的信息。

    这应该可行,请尝试:

    SELECT 
       id, 
       name,
       CASE WHEN tfra.entry_id is null THEN teng.name ELSE tfra.name END as name 
    FROM table 
    LEFT JOIN table2 tfra ON id = tfra.entity_id AND tfra.lang='fra'
    LEFT JOIN table2 teng ON id = teng.entity_id AND teng.lang='eng'
    WHERE (IF lang = 'fra' return french name otherwise return just english name) 
    ORDER BY name ASC
    

    如果您运行的是MySQL 8.0,我建议您使用以下窗口功能:

    select entity_id, name, lang
    from (
        select t2.*,
            row_number() over(partition by entity_id order by field(lang, 'fra', 'eng')) rn
        from table2 t2
    ) t2
    where rn = 1
    
    如果需要联接另一个表(从示例数据中看不明显),可以执行以下操作:

    select t1.*, t2.name, t2.lang
    from table1 t1
    left join (
        select t2.*,
            row_number() over(partition by entity_id order by field(lang, 'fra', 'eng')) rn
        from table2 t2
    ) t2 on t2.entity_id = t1.id and t2.rn = 1
    

    是什么阻止了你尝试这一点?我不知道如何写“if语句”,如果两种语言都存在,只返回一个“法语”忽略“英语”,但如果“英语”仅可用,只返回它。就像在lang=“fra”中添加了一些内容,但如果不存在,只返回一个“eng”有什么想法吗?有,谢谢,但是我可以修改表结构在SQL中使用子查询进行拆分和联接。tnx sir看起来工作了数百万次!请你能投票的问题,如果你发现它使用完整的tnx!