使用ids保存层次结构替换类别名称

时间:2015-10-23 18:10:37

标签: mysql

我有这样的options_for_select表:

data

用其ID替换类别和子类别名称,将它们移动到其他表格的最佳方法是什么?得到这个结果:

category_name | subcategory_name | other data --------------------------------------------- fruits | apples | ... fruits | oragnes | ... 表:

category

id | name | parent_id ------------------------ 1 | fruits | 0 2 | apples | 1 3 | oragnes| 1 表:

data

我可以使用一些select distinct和join查询手动完成所有操作,但还有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

可能有一种更简单的方法可以做到这一点;但是mysql并不包含我在这里使用的许多窗口函数,也不包含常用的表表达式,也不包含用户变量的视图....所以我留下了一点点混乱但似乎工作......

我假设您当前的模型可能有N级。  我还假设子类别在多个类别下不存在。

这是做什么的

  1. 生成一组包含"名称"的数据。我们必须在没有父母的情况下找到所有类别的名称,并将这些名称与父母的名字联系起来。
  2. 然后我们分配了一个用户变量(@)来为每个项目生成一个新的ID。使用了两个不同的变量,因此编号没有从一个查询换行到下一个查询。
  3. 然后我们将该查询复制到两个单独的子查询中(在我的示例中为A,B)并将它们连接起来以获取父ID。
  4. SQL Fiddle

    -- distinct used to get 1 record for each parent and an outer wraper to return just desired results
    
    Select Distinct A.ID as ID, A.SubCategory_name name, B.ID as Parent_ID  from (
      ---this select assigns a row number for each named value
      Select @rn:=@rn+1 ID, t1.*
      from (
        --Get just parents without any parent
        Select NULL as Category_Name, F1.category_name as SubCategory_name
        FROM (Select distinct category_Name from foo) F1 
        LEFT JOIN Foo F2 
          on F1.Category_name = F2.SubCategory_name
        where F2.SubCategory_name is null
    
        UNION ALL
        --get just children of parents
        SELECT category_name, subcategory_Name from foo) T1
        -- Used to get a row number assigned
        CROSS JOIN (SELECT @rn:=0) t2
        -- used to ensure same order applied to both queries so numbers match
        -- though now that I think about it I don't think we need numbers in 2nd query
        order by Category_name, SubCategory_Name) A
    
     LEFT JOIN (
      Select @r:=@r+1 ID, t1.*
      from (
        Select NULL as Category_Name, F1.category_name as SubCategory_name
        FROM (Select distinct category_Name from foo) F1 
        LEFT JOIN Foo F2 
        on F1.Category_name = F2.SubCategory_name
        where F2.SubCategory_name is null
    
        UNION ALL
        SELECT category_name, subcategory_Name from foo) T1
        CROSS JOIN (SELECT @r:=0) t2
       order by Category_name, SubCategory_Name) B
    on B.SubCategory_Name = A.Category_name
    

    并从上面选择你可以创建表,或填充表。