簡體   English   中英

SQL Server 2012:如何從原始表到派生產品表獲取多達5個層次結構的數據

[英]SQL Server 2012: How to get up to 5 hierarchy levels of data from original to derived product table

我有一個包含3列的表格:

Id (identity),
Sku_Parent (varchar(10)),
Sku_Child (varchar(10))

我想獲得幫助來編寫遞歸查詢以獲取多達5個父子關系級別。

當插入新派生產品時,新派生產品也可以(最終)用作父級產品。 我希望能夠跟蹤每個新派生產品的歷史記錄(向下5級)並找到頂級父級產品。 我希望這是一個明確的解釋。

這是當前駐留在我的表中的示例數據:

7038    N0179890    N0180323
7039    N0180323    N0180328
7040    N0180323    N0180329
7041    N0180323    N0180330
7042    N0180323    N0180331
7043    N0180323    N0180332
7044    N0180323    N0180333
7045    N0180323    N0180334

我已經找到了示例,但是我發現的示例假設只有一個父記錄並且具有空值。

這是獲取表數據副本的鏈接:

https://drive.google.com/open?id=1hP7kRQsl_8YzEu4dK9Z8J91y-2Gvh7Qi

請指教。 非常感謝。

更新

我看到sku P55645用於創建9個派生產品,在這種情況下,沒有一個派生產品成為父項。 沒關系
我只是認為,如果不顯示9行,而是從頂層sku開始,每個草圖填充在一行中,可能會更容易閱讀。

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

像這樣的東西(改編自這個答案 ):

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

表架構:

在此處輸入圖片說明

適應您的表模式:

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'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM