SQL Server 2012:如何获得从原始产品到派生产品的最多 5 个层次结构级别的数据 table
SQL Server 2012: How to get up to 5 hierarchy levels of data from original to derived product table
我有一个包含 3 列的 table:
Id (identity),
Sku_Parent (varchar(10)),
Sku_Child (varchar(10))
我想获得帮助来编写递归查询以获得最多 5 个父子关系级别。
插入新派生产品时,新派生产品也(最终)可以用作父产品。我希望能够跟踪每个新派生产品的历史,向下 5 个级别并找到顶级父级。我希望这是一个明确的解释。
这是当前驻留在我的 table 中的示例数据:
7038 N0179890 N0180323
7039 N0180323 N0180328
7040 N0180323 N0180329
7041 N0180323 N0180330
7042 N0180323 N0180331
7043 N0180323 N0180332
7044 N0180323 N0180333
7045 N0180323 N0180334
我找到了例子,但我发现的例子假设只有一个父记录并且有一个空值。
这是一个 link 来获取 table 数据的副本:
https://drive.google.com/open?id=1hP7kRQsl_8YzEu4dK9Z8J91y-2Gvh7Qi
请指教。非常感谢。
更新
我看到 sku P55645 被用来创建 9 个派生产品,在这种情况下 none 个派生产品成为父产品。完全可以。
我只是认为,如果不是显示 9 行,而是从顶级 sku 开始,每个 skus 都被塞进一行,可能会更容易阅读。
As it currently is:
P0055645 P0098245 P0055645, P0098245
P0055645 P0110959 P0055645, P0110959
P0055645 P0110960 P0055645, P0110960
P0055645 P0110961 P0055645, P0110961
P0055645 P0110962 P0055645, P0110962
P0055645 P0110963 P0055645, P0110963
P0055645 P0110964 P0055645, P0110964
P0055645 P0110965 P0055645, P0110965
P0055645 P0157714 P0055645, P0157714
I think this might read better:
P0055645, P0098245, P0110959, P0110960, P0110961, P0110962, P0110963, P0110964, P0110965, P0157714
This is also current output that I am having a hard time following:
Parent Derived Hierarchy
P0172879 P0178192 P0172879, P0178192
P0178192 P0178206 P0172879, P0178192, P0178206 - until this point i see that the relationship of parent child and then the chil becoming a parent is well illustrated
P0178206 P0178219 P0172879, P0178192, P0178206, P0178219 -- but then P0178206 becomes the parent of 6 new skus. Do you think this looks good, or should the output be like the first example I described?
P0178206 P0178220 P0172879, P0178192, P0178206, P0178220
P0178206 P0178221 P0172879, P0178192, P0178206, P0178221
P0178206 P0178222 P0172879, P0178192, P0178206, P0178222
P0178206 P0178223 P0172879, P0178192, P0178206, P0178223
P0178206 P0178224 P0172879, P0178192, P0178206, P0178224
第二次更新
P0170926 P0170928 P0170926, P0170928 -- if sku load on form is P0170926, then the query will load a record-set of 2 records
P0170928 P0170929 P0170926, P0170928, P0170929 -- if user loads on form P0170928 then it will load 3 records including P0170926
P0170932 P0174069 P0170932, P0174069 -- here if user loads P0170932 the record set will only contain one record, shouldn't all the records up to P0174075 be also included?
P0170932 P0174070 P0170932, P0174070
P0170932 P0174071 P0170932, P0174071
P0170932 P0174072 P0170932, P0174072
P0170932 P0174073 P0170932, P0174073
P0170932 P0174074 P0170932, P0174074
P0170932 P0174075 P0170932, P0174075
像这样(改编自this answer):
WITH Skus as
(
SELECT
Sku_Parent Sku
, CAST(NULL AS varchar(10)) Parent
, CAST(Sku_Parent AS varchar(max)) Hierarchy
FROM YourTable P
WHERE Sku_Parent NOT IN (SELECT Sku_Child FROM YourTable)
UNION ALL
SELECT
P.Sku_Child
, P.Sku_Parent
, M.Hierarchy + ', ' + CAST(P.Sku_Child AS varchar(max))
FROM
YourTable P
JOIN Skus M ON M.Sku = P.Sku_Parent
)
SELECT DISTINCT
Sku
, Parent
, Hierarchy
FROM Skus
Table 架构:
适应您的 table 架构:
WITH [Skus]
AS
(
SELECT
[P].[SKU_original] [Sku]
, CAST(NULL AS VARCHAR(12)) [Parent]
, CAST([P].[SKU_original] AS VARCHAR(MAX)) [Hierarchy]
FROM [dbo].[production_derived_products] [P]
WHERE [P].[SKU_original] NOT IN
(
SELECT [SKU_derived]
FROM [dbo].[production_derived_products]
)
UNION ALL
SELECT
[P].[SKU_derived]
, [P].[SKU_original]
, [M].[Hierarchy] + ', ' + CAST([P].[SKU_derived] AS VARCHAR(MAX))
FROM
[dbo].[production_derived_products] [P]
JOIN [Skus] [M] ON [M].[Sku] = [P].[SKU_original]
)
SELECT DISTINCT
[Skus].[Sku]
, [Skus].[Parent]
, [Skus].[Hierarchy]
FROM [Skus]
;
更新
关于这个:
P0170932 P0174069 P0170932, P0174069 -- here if user loads P0170932 the record set will only contain one record, shouldn't all the records up to P0174075 be also included?
P0170932 P0174070 P0170932, P0174070
P0170932 P0174071 P0170932, P0174071
P0170932 P0174072 P0170932, P0174072
P0170932 P0174073 P0170932, P0174073
P0170932 P0174074 P0170932, P0174074
P0170932 P0174075 P0170932, P0174075
它不会加载所有记录列表的原因是因为该列用于层次结构,即您建议的输出将 P0174070 描述为 P0174069 的子项,而实际上它是 P0170932 的子项。
无论如何,我已经尝试过很多次了,我认为下面的内容会为您提供您需要的任何东西(如果没有请告诉我)。
我在末尾使用了 WHERE
子句,因此您可以 运行 这个并获得快速演示,但您可以删除它以查看所有内容。
WITH Skus as
(
SELECT
SKU_original Sku
, CAST(NULL AS varchar(12)) Parent
, SKU_original AbsoluteHierarchicalParent
, CAST(SKU_original AS varchar(max)) Hierarchy
, 0 [Level]
FROM production_derived_products P
WHERE SKU_original NOT IN (SELECT SKU_derived FROM production_derived_products)
UNION ALL
SELECT
P.SKU_derived
, P.SKU_original
, M.AbsoluteHierarchicalParent
, M.Hierarchy + ', ' + CAST(P.SKU_derived AS varchar(max))
, M.[Level] + 1
FROM
production_derived_products P
JOIN Skus M ON M.Sku = P.SKU_original
)
,
SkusDistinct
AS
(
SELECT DISTINCT
Sku
, Parent
, AbsoluteHierarchicalParent
, Hierarchy
, [Level]
FROM Skus
)
,
SkuHierarchies
AS
(
SELECT
Sku
, Sku StartSku
, 0 [Level]
FROM
(
SELECT SKU_original Sku
FROM production_derived_products
UNION
SELECT SKU_derived
FROM production_derived_products
) AllSkus
UNION ALL
SELECT
P.SKU_derived
, M.StartSku
, M.[Level] + 1
FROM
production_derived_products P
JOIN SkuHierarchies M ON M.Sku = P.SKU_original
)
,
SkuHierarchiesDistinct
AS
(
SELECT DISTINCT
Sku
, StartSku
, [Level]
FROM SkuHierarchies
)
SELECT
SD1.Sku
, SD1.Parent
, SD1.AbsoluteHierarchicalParent
,
STUFF(
(
SELECT ', ' + SD2.Sku
FROM SkusDistinct SD2
WHERE SD2.Parent = SD1.Sku
ORDER BY SD2.Sku
FOR XML PATH ('')
)
, 1, 2, '') ImmediateChildren
, SD1.Hierarchy Heritage
, SD1.[Level]
,
STUFF(
(
SELECT ', ' + H.Sku + ' (' + CAST(H.[Level] AS varchar) + ')'
FROM SkuHierarchiesDistinct H
WHERE H.StartSku = SD1.Sku
ORDER BY
H.[Level]
, H.Sku
FOR XML PATH ('')
)
, 1, 2, '') SkuHierarchyByLevel
, (SELECT MAX([Level]) + 1 FROM SkuHierarchiesDistinct WHERE StartSku = SD1.Sku) SkuHierarchyTotalLevels
,
STUFF(
(
SELECT ', ' + SD2.Sku + ' (' + CAST(SD2.[Level] AS varchar) + ')'
FROM SkusDistinct SD2
WHERE SD2.AbsoluteHierarchicalParent = SD1.AbsoluteHierarchicalParent
ORDER BY
SD2.[Level]
, SD2.Sku
FOR XML PATH ('')
)
, 1, 2, '') FullHierarchyByLevel
, MAX(SD1.[Level]) OVER (PARTITION BY AbsoluteHierarchicalParent) + 1 FullHierarchyTotalLevels
FROM SkusDistinct SD1
WHERE AbsoluteHierarchicalParent = 'P0172879'
我有一个包含 3 列的 table:
Id (identity),
Sku_Parent (varchar(10)),
Sku_Child (varchar(10))
我想获得帮助来编写递归查询以获得最多 5 个父子关系级别。
插入新派生产品时,新派生产品也(最终)可以用作父产品。我希望能够跟踪每个新派生产品的历史,向下 5 个级别并找到顶级父级。我希望这是一个明确的解释。
这是当前驻留在我的 table 中的示例数据:
7038 N0179890 N0180323
7039 N0180323 N0180328
7040 N0180323 N0180329
7041 N0180323 N0180330
7042 N0180323 N0180331
7043 N0180323 N0180332
7044 N0180323 N0180333
7045 N0180323 N0180334
我找到了例子,但我发现的例子假设只有一个父记录并且有一个空值。
这是一个 link 来获取 table 数据的副本:
https://drive.google.com/open?id=1hP7kRQsl_8YzEu4dK9Z8J91y-2Gvh7Qi
请指教。非常感谢。
更新
我看到 sku P55645 被用来创建 9 个派生产品,在这种情况下 none 个派生产品成为父产品。完全可以。
我只是认为,如果不是显示 9 行,而是从顶级 sku 开始,每个 skus 都被塞进一行,可能会更容易阅读。
As it currently is:
P0055645 P0098245 P0055645, P0098245
P0055645 P0110959 P0055645, P0110959
P0055645 P0110960 P0055645, P0110960
P0055645 P0110961 P0055645, P0110961
P0055645 P0110962 P0055645, P0110962
P0055645 P0110963 P0055645, P0110963
P0055645 P0110964 P0055645, P0110964
P0055645 P0110965 P0055645, P0110965
P0055645 P0157714 P0055645, P0157714
I think this might read better:
P0055645, P0098245, P0110959, P0110960, P0110961, P0110962, P0110963, P0110964, P0110965, P0157714
This is also current output that I am having a hard time following:
Parent Derived Hierarchy
P0172879 P0178192 P0172879, P0178192
P0178192 P0178206 P0172879, P0178192, P0178206 - until this point i see that the relationship of parent child and then the chil becoming a parent is well illustrated
P0178206 P0178219 P0172879, P0178192, P0178206, P0178219 -- but then P0178206 becomes the parent of 6 new skus. Do you think this looks good, or should the output be like the first example I described?
P0178206 P0178220 P0172879, P0178192, P0178206, P0178220
P0178206 P0178221 P0172879, P0178192, P0178206, P0178221
P0178206 P0178222 P0172879, P0178192, P0178206, P0178222
P0178206 P0178223 P0172879, P0178192, P0178206, P0178223
P0178206 P0178224 P0172879, P0178192, P0178206, P0178224
第二次更新
P0170926 P0170928 P0170926, P0170928 -- if sku load on form is P0170926, then the query will load a record-set of 2 records
P0170928 P0170929 P0170926, P0170928, P0170929 -- if user loads on form P0170928 then it will load 3 records including P0170926
P0170932 P0174069 P0170932, P0174069 -- here if user loads P0170932 the record set will only contain one record, shouldn't all the records up to P0174075 be also included?
P0170932 P0174070 P0170932, P0174070
P0170932 P0174071 P0170932, P0174071
P0170932 P0174072 P0170932, P0174072
P0170932 P0174073 P0170932, P0174073
P0170932 P0174074 P0170932, P0174074
P0170932 P0174075 P0170932, P0174075
像这样(改编自this answer):
WITH Skus as
(
SELECT
Sku_Parent Sku
, CAST(NULL AS varchar(10)) Parent
, CAST(Sku_Parent AS varchar(max)) Hierarchy
FROM YourTable P
WHERE Sku_Parent NOT IN (SELECT Sku_Child FROM YourTable)
UNION ALL
SELECT
P.Sku_Child
, P.Sku_Parent
, M.Hierarchy + ', ' + CAST(P.Sku_Child AS varchar(max))
FROM
YourTable P
JOIN Skus M ON M.Sku = P.Sku_Parent
)
SELECT DISTINCT
Sku
, Parent
, Hierarchy
FROM Skus
Table 架构:
适应您的 table 架构:
WITH [Skus]
AS
(
SELECT
[P].[SKU_original] [Sku]
, CAST(NULL AS VARCHAR(12)) [Parent]
, CAST([P].[SKU_original] AS VARCHAR(MAX)) [Hierarchy]
FROM [dbo].[production_derived_products] [P]
WHERE [P].[SKU_original] NOT IN
(
SELECT [SKU_derived]
FROM [dbo].[production_derived_products]
)
UNION ALL
SELECT
[P].[SKU_derived]
, [P].[SKU_original]
, [M].[Hierarchy] + ', ' + CAST([P].[SKU_derived] AS VARCHAR(MAX))
FROM
[dbo].[production_derived_products] [P]
JOIN [Skus] [M] ON [M].[Sku] = [P].[SKU_original]
)
SELECT DISTINCT
[Skus].[Sku]
, [Skus].[Parent]
, [Skus].[Hierarchy]
FROM [Skus]
;
更新
关于这个:
P0170932 P0174069 P0170932, P0174069 -- here if user loads P0170932 the record set will only contain one record, shouldn't all the records up to P0174075 be also included?
P0170932 P0174070 P0170932, P0174070
P0170932 P0174071 P0170932, P0174071
P0170932 P0174072 P0170932, P0174072
P0170932 P0174073 P0170932, P0174073
P0170932 P0174074 P0170932, P0174074
P0170932 P0174075 P0170932, P0174075
它不会加载所有记录列表的原因是因为该列用于层次结构,即您建议的输出将 P0174070 描述为 P0174069 的子项,而实际上它是 P0170932 的子项。
无论如何,我已经尝试过很多次了,我认为下面的内容会为您提供您需要的任何东西(如果没有请告诉我)。
我在末尾使用了 WHERE
子句,因此您可以 运行 这个并获得快速演示,但您可以删除它以查看所有内容。
WITH Skus as
(
SELECT
SKU_original Sku
, CAST(NULL AS varchar(12)) Parent
, SKU_original AbsoluteHierarchicalParent
, CAST(SKU_original AS varchar(max)) Hierarchy
, 0 [Level]
FROM production_derived_products P
WHERE SKU_original NOT IN (SELECT SKU_derived FROM production_derived_products)
UNION ALL
SELECT
P.SKU_derived
, P.SKU_original
, M.AbsoluteHierarchicalParent
, M.Hierarchy + ', ' + CAST(P.SKU_derived AS varchar(max))
, M.[Level] + 1
FROM
production_derived_products P
JOIN Skus M ON M.Sku = P.SKU_original
)
,
SkusDistinct
AS
(
SELECT DISTINCT
Sku
, Parent
, AbsoluteHierarchicalParent
, Hierarchy
, [Level]
FROM Skus
)
,
SkuHierarchies
AS
(
SELECT
Sku
, Sku StartSku
, 0 [Level]
FROM
(
SELECT SKU_original Sku
FROM production_derived_products
UNION
SELECT SKU_derived
FROM production_derived_products
) AllSkus
UNION ALL
SELECT
P.SKU_derived
, M.StartSku
, M.[Level] + 1
FROM
production_derived_products P
JOIN SkuHierarchies M ON M.Sku = P.SKU_original
)
,
SkuHierarchiesDistinct
AS
(
SELECT DISTINCT
Sku
, StartSku
, [Level]
FROM SkuHierarchies
)
SELECT
SD1.Sku
, SD1.Parent
, SD1.AbsoluteHierarchicalParent
,
STUFF(
(
SELECT ', ' + SD2.Sku
FROM SkusDistinct SD2
WHERE SD2.Parent = SD1.Sku
ORDER BY SD2.Sku
FOR XML PATH ('')
)
, 1, 2, '') ImmediateChildren
, SD1.Hierarchy Heritage
, SD1.[Level]
,
STUFF(
(
SELECT ', ' + H.Sku + ' (' + CAST(H.[Level] AS varchar) + ')'
FROM SkuHierarchiesDistinct H
WHERE H.StartSku = SD1.Sku
ORDER BY
H.[Level]
, H.Sku
FOR XML PATH ('')
)
, 1, 2, '') SkuHierarchyByLevel
, (SELECT MAX([Level]) + 1 FROM SkuHierarchiesDistinct WHERE StartSku = SD1.Sku) SkuHierarchyTotalLevels
,
STUFF(
(
SELECT ', ' + SD2.Sku + ' (' + CAST(SD2.[Level] AS varchar) + ')'
FROM SkusDistinct SD2
WHERE SD2.AbsoluteHierarchicalParent = SD1.AbsoluteHierarchicalParent
ORDER BY
SD2.[Level]
, SD2.Sku
FOR XML PATH ('')
)
, 1, 2, '') FullHierarchyByLevel
, MAX(SD1.[Level]) OVER (PARTITION BY AbsoluteHierarchicalParent) + 1 FullHierarchyTotalLevels
FROM SkusDistinct SD1
WHERE AbsoluteHierarchicalParent = 'P0172879'