提问人:HedgeHog 提问时间:10/25/2023 最后编辑:HedgeHog 更新时间:10/25/2023 访问量:38
如何将不同层次的product_groups和规格联合到最深层次?
How to UNION product_groups and specifications of different hierachy level to deepest one?
问:
场景 - 所有有效的类别/产品组及其对其中所有产品的有效规格都将被确定。
- 产品具有不同的规格/功能
- 产品始终挂在产品组树中的最低层次结构级别上。
- 规格可以附加到不同的级别,在这种情况下,可以假设它们只附加到最高(非常通用)和最低级别(相当非常特殊的尺寸、压力规格......
由于产品在最低级别链接,因此在我看来,最简单的方法是将上层存在的所有规范组合到最低级别的路径中。
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
答:
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 9
product_groups
parent_id 3
id 4
1赞
nbk
10/25/2023
这将是一个新问题,因为它会体贴地改变答案,为了让它工作,你可以做一个递归的 CTE,看看你是否得到一个可以提取所需 ID 的结果select * FROM CTE after the first
评论