繁体   English   中英

MySQL递归查询,用于查找多对多关系的所有父级

[英]MySQL recursive query for finding all parents of a many-to-many relationship

编辑 在标记为重复之前,请考虑这一点

通用CTE或重复联接或类似的解决方案不能完全满足问题的前提。 这些解决方案针对一个且仅一个根(产品)起作用,而当前的问题则要求遍历和扁平化表或查询中的所有根,而没有循环。

问题定义

我有三个表来定义某些产品的特征:

  • 规格
+----|------------------|----------|--------+
| id |             name |     type | status |
|----|------------------|----------|--------|
|  1 |           height |    float |      0 |
|  2 |            width |    float |      0 |
|  3 |           length |    float |      0 |
|  4 |           weight |    float |      0 |
|  5 |           colour |      int |      0 |
|  6 |         material |      int |      0 |
|  7 |     manufacturer |      int |      0 |
|  8 |       durability |    float |      0 |
|  9 |     battery_type |      int |      0 |
| 10 | battery_capacity |    float |      0 |
| 11 |     connectivity | set<int> |      0 |
| 12 |             page |      int |      0 |
| 13 |             name |   string |      0 |
| 14 |      description |   string |      0 |
+----|------------------|----------|--------+
  • 团体
+----|-------------------|--------+
| id |              name | status |
|----|-------------------|--------|
|  1 |         cellphone |      0 |
|  2 |          notebook |      0 |
|  3 |          portable |      0 |
|  4 |       workstation |      0 |
|  5 |                pc |      0 |
|  6 |          computer |      0 |
|  7 | electronic_device |      0 |
|  8 |              book |      0 |
|  9 |          sizeable |      0 |
| 10 |         volumable |      0 |
| 11 |           general |      0 |
+----|-------------------|--------+
  • Specification_groups
+----|----------|------------------|--------+
| id | group_id | specification_id | status |
|----|----------|------------------|--------|
|  1 |       11 |               13 |      0 |
|  2 |       11 |               14 |      0 |
|  3 |       11 |                5 |      0 |
|  4 |       10 |                1 |      0 |
|  5 |        9 |                2 |      0 |
|  6 |        9 |                3 |      0 |
|  7 |        8 |               12 |      0 |
|  8 |        3 |                6 |      0 |
|  9 |        3 |                9 |      0 |
| 10 |        3 |               10 |      0 |
| 11 |        7 |                7 |      0 |
| 12 |        7 |               11 |      0 |
+----|----------|------------------|--------+
  • group_groups
+----|----------|--------------------|--------+
| id | group_id | group_reference_id | status |
|----|----------|--------------------|--------|
|  1 |        3 |                  1 |      0 |
|  2 |        3 |                  2 |      0 |
|  3 |        3 |                  8 |      0 |
|  4 |        6 |                  4 |      0 |
|  5 |        6 |                  5 |      0 |
|  6 |        7 |                  1 |      0 |
|  7 |        7 |                  2 |      0 |
|  8 |        7 |                  4 |      0 |
|  9 |        7 |                  5 |      0 |
| 10 |        9 |                  7 |      0 |
| 11 |        9 |                  8 |      0 |
| 12 |       10 |                  7 |      0 |
| 12 |       11 |                  7 |      0 |
| 12 |       11 |                  8 |      0 |
+----|----------|--------------------|--------+
  • product_groups
+----|--------|-------|--------+
| id |   name | group | status |
|----|--------|-------|--------|
|  1 | phone1 |     1 |      0 |
|  2 |  book1 |     8 |      0 |
+----|--------|-------|--------+

理想情况下,我想获取产品的所有规格属性,所有树状线上的状态均为0,但是只知道产品属于哪个组是可以接受的。

结果可能如下所示:

  • 结果
+---------|-------------|--------------|-------------------|----------|--------+
| row_num |  product_id | product_name |     product_group | group_id | status |
|---------|-------------|--------------|-------------------|----------|--------|
|       1 |           1 |       phone1 |         cellphone |        1 |      0 |
|       2 |           1 |       phone1 |          portable |        3 |      0 |
|       3 |           1 |       phone1 | electronic_device |        7 |      0 |
|       4 |           1 |       phone1 |           sizable |        9 |      0 |
|       5 |           1 |       phone1 |         volumable |       10 |      0 |
|       6 |           1 |       phone1 |           general |       11 |      0 |
|       7 |           2 |        book1 |              book |        8 |      0 |
|       8 |           2 |        book1 |          portable |        3 |      0 |
|       9 |           2 |        book1 |           sizable |        9 |      0 |
|      10 |           2 |        book1 |           general |       11 |      0 |
+---------|-------------|--------------|-------------------|----------|--------+

如果其他人也想这样做,这就是答案。 诀窍是在递归参数中使用非递归初始选择参数作为常量:

    with recursive 
        q as (
            select * from product_groups as pg where ur.`status` = 0 
        )
        , ancestors as (
            (
                select q.id as `product_id`, q.product_name as `product_name`, gg.group_id as `group_id`, gg.group_reference_id as `group_reference_id`
                from group_groups as gg
                    join q on gg.group_id = q.group_id
                where gg.`status` = 0
            )
            union
            (
                select q.id as `product_id`, q.product_name as `product_name`, null as `group_id`, q.group_id as `group_reference_id`
                from q
            )
            union
            (
                select a.id as `product_id`, a.product_name as `product_name`, gg.group_id as `group_id`, gg.group_reference_id as `group_reference_id`
                from group_groups as gg, ancestors as a
                where gg.group_id = a.group_reference_id and gg.`status` = 0
            )
        )
    select distinct
        t.id as `product_id`, t.`group_id` as `group_id`, t.specification_id as `specification_id`, t.product_name as `product_name`, t.group_name as `group_name`, s.name as `specification_name`
    from 
    (
        select a.product_id, a.group_reference_id as `group_id`, sg.specification_id as `specification_id`, a.product_name, g.name as `group_name`
        from ancestors as a
            right join specification_groups as sg on a.group_reference_id = sg.group_id
        where a.product_id is not null and sg.`status` = 0
    ) as t
        join specifications as s on t.specification_id = s.id
    order by product_id asc, group_id, asc, specification_id asc
    ;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM