如何将不同层次的product_groups和规格联合到最深层次?

How to UNION product_groups and specifications of different hierachy level to deepest one?

提问人:HedgeHog 提问时间:10/25/2023 最后编辑:HedgeHog 更新时间:10/25/2023 访问量:38

问:

场景 - 所有有效的类别/产品组及其对其中所有产品的有效规格都将被确定。

  • 产品具有不同的规格/功能
  • 产品始终挂在产品组树中的最低层次结构级别上。
  • 规格可以附加到不同的级别,在这种情况下,可以假设它们只附加到最高(非常通用)和最低级别(相当非常特殊的尺寸、压力规格......

由于产品在最低级别链接,因此在我看来,最简单的方法是将上层存在的所有规范组合到最低级别的路径中。


product_groups
编号 parent_id
1
2 1
3 2
4 3
5
6 5
7 6
8 7
specification_to_group
编号 product_group_id specification_id
1 1 1
2 1 2
3 4 10
4 4 11
5 4 12
6 5 1
7 5 3
8 7 12
结果
product_group_id specification_id
4 1
4 2
4 10
4 11
4 12
8 1
8 3
8 12

一种方法是尝试使用帮助表,并减少泛型。

SELECT
    lst.id AS lst,
    up1.id AS up1,
    up2.id AS up2,
    up3.id AS up3,
    up4.id AS up4
FROM
    product_groups lst 
        LEFT JOIN
    product_groups up1 ON lst.parent_id = up1.id
        LEFT JOIN
    product_groups up2 ON up1.parent_id = up2.id
        LEFT JOIN
    product_groups up3 ON up2.parent_id = up3.id
        LEFT JOIN
    product_groups up4 ON up3.parent_id = up4.id
WHERE
    lst.id NOT IN
    (SELECT DISTINCT parent_id
        FROM product_groups
        WHERE parent_id IS NOT NULL
)
        
SELECT g.lst, s.specification_id
        FROM ht_tree g
               LEFT JOIN specification_to_group s ON g.lst = s.product_group_id
               UNION SELECT g.lst, s.specification_id
        FROM ht_tree g
               LEFT JOIN specification_to_group s ON g.up1 = s.product_group_id
UNION SELECT g.lst, s.specification_id
        FROM ht_tree g
               LEFT JOIN specification_to_group s ON g.up2 = s.product_group_id
UNION SELECT g.lst, s.specification_id
        FROM ht_tree g
               LEFT JOIN specification_to_group s ON g.up3 = s.product_group_id
UNION 
SELECT g.lst, s.specification_id
        FROM ht_tree g
               LEFT JOIN specification_to_group s ON g.up4 = s.product_group_id;
;

由于没有创建表的权限,也没有其他选项来持久化已经准备好的数据,因此我会考虑一个.CTE

sql mariadb 联合 common-table-expression hierarchical-data

评论


答:

2赞 nbk 10/25/2023 #1

这是使用递归 CTE 的经典机会

WITH recursive  CTE AS(
SELECT `id`, `parent_id`, ROW_NUMBER() OVER (ORDER By id) rn, 1 lvl
FROM  product_groups
WHERE `parent_id` IS NULL
  UNION ALL

  SELECT P1.id, P1.parent_id , M.rn, M.lvl+1 AS LVL
  FROM product_groups P1  
  INNER JOIN CTE M
  ON M.id = P1.parent_id),
  getmax as(
SELECT `id`, MAX(id) OVER(PARTITION BY rn) m FROM CTE
ORDER BY rn)
SELECT sp.id, g.m, sp.`specification_id`
  FROM specification_to_group sp JOIN getmax g ON sp.`product_group_id` = g.id
ORDER By sp.id
编号 m specification_id
1 4 1
2 4 2
3 4 10
4 4 11
5 4 12
6 8 1
7 8 3
8 8 12

小提琴

评论

0赞 HedgeHog 10/25/2023
感谢您的夜班,我已经尝试过了,只要,大概是应该在问题中添加的细节,没有结构的嵌套,这也完美地运行,嵌套的意义是会有一个 in ,它也被分配给 ,它会覆盖输出。我应该为此发布一个新问题,还是您可以简要介绍一下。再次非常感谢您id 9product_groupsparent_id 3id 4
1赞 nbk 10/25/2023
这将是一个新问题,因为它会体贴地改变答案,为了让它工作,你可以做一个递归的 CTE,看看你是否得到一个可以提取所需 ID 的结果select * FROM CTE after the first