递归查询和INNER JOIN

时间:2015-08-31 18:09:24

标签: sql sql-server-2008

我遇到了一个使用递归的查询,并想知道你们是否可以帮助我。

我在下面有这个查询,它基于ShipQuantity,然后列出了记录数。例如,mfgPN“ABC123”的ShipQuantity为4,它将列出4条记录,编号为1,2,3,4。

WITH feedInfo
AS (
    SELECT df1.RecID, MfgPN, LinkID, ShipQuantity, 1 AS Number 
    FROM EXT_DistributorFeed df1
    WHERE 1 = 1
    AND df1.mfgPN IN ('ABC1', 'ABC2')  

    UNION ALL

    SELECT df2.RecID, df2.MfgPN, df2.LinkID, df2.ShipQuantity, feedInfo.number + 1 AS Number 
    FROM EXT_DistributorFeed df2
    INNER JOIN feedInfo ON df2.RecID = feedInfo.RecID
    WHERE 1 = 1
    AND number < feedInfo.ShipQuantity
    AND df2.mfgPN IN ('ABC1', 'ABC2')
)
Select feedInfo.*
From feedInfo
OPTION (maxrecursion 20000);

假设结果是

RecID   MfgPN   LinkID  ShipQuantity    Number 
101     ABC1    L11111  4               1
102     ABC1    L11111  4               2
103     ABC1    L11111  4               3
104     ABC1    L11111  4               4
105     ABC2    L22222  2               1
106     ABC2    L22222  2               2   

现在,我有另一个表“EXT_DistributorFeedDetail”,其中可能包含序列号#(某些部分#有序列号而某些部分#没有)。该表只有两列:(1)LinkID和(2)SerialNo。像这样:

EXT_DistributorFeedDetail
LinkID  SerialNo
L22222  S999999 
L22222  S888888

我想将feedInfo与EXT_DistributorFeedDetail表一起加入以获得如下结果:

RecID   MfgPN   LinkID  ShipQuantity    Number  Serial
101     ABC1    L11111  4               1       NULL
102     ABC1    L11111  4               2       NULL
103     ABC1    L11111  4               3       NULL
104     ABC1    L11111  4               4       NULL
105     ABC2    L22222  2               1       S99999
106     ABC2    L22222  2               2       S88888

任何有帮助的专家都会非常感激。

谢谢,

3 个答案:

答案 0 :(得分:1)

您似乎正在尝试将递归查询中的LinkID和Number与EXT_DistributorFeedDetail表中的LinkID和行号进行匹配

WITH feedInfo
AS (
    SELECT df1.RecID, MfgPN, LinkID, ShipQuantity, 1 AS Number 
    FROM EXT_DistributorFeed df1
    WHERE 1 = 1
    AND df1.mfgPN IN ('ABC1', 'ABC2')  

    UNION ALL

    SELECT df2.RecID, df2.MfgPN, df2.LinkID, df2.ShipQuantity, feedInfo.number + 1 AS Number 
    FROM EXT_DistributorFeed df2
    INNER JOIN feedInfo ON df2.RecID = feedInfo.RecID
    WHERE 1 = 1
    AND number < feedInfo.ShipQuantity
    AND df2.mfgPN IN ('ABC1', 'ABC2')
)
Select  fi.*,
        dfd.SerialNo [Serial]
From    feedInfo fi
        LEFT JOIN (SELECT *, ROW_NUMBER() OVER (PARTITION BY LinkID ORDER BY SerialNo) rn, 
                   FROM EXT_DistributorFeedDetail) dfd 
           ON dfd.LinkID = fi.LinkID AND dfd.rn = fi.Number
OPTION (maxrecursion 20000);

根据您希望EXT_DistributorFeedDetail表中的序列号的顺序,您需要在Window函数ROW_NUMBER() OVER (PARTITION BY LinkID ORDER BY SerialNo)中更改顺序,如果您按顺序取出它将是随机的并且可能会更改

答案 1 :(得分:1)

看起来您想按照数字的降序加入SerialNo。您可以通过将查询的最后一部分更改为:

来完成此操作
Private Sub Workbook_Activate()
    Application.ScreenUpdating = False

    ThisWorkbook.Sheets(2).Activate
    ActiveWindow.DisplayGridlines = False
    ActiveWindow.DisplayHeadings = False

    ThisWorkbook.Sheets(1).Activate
    ActiveWindow.DisplayGridlines = False
    ActiveWindow.DisplayHeadings = False

    Application.DisplayFullScreen = True
    Application.DisplayFormulaBar = False

    Application.ScreenUpdating = True
End Sub

Private Sub Workbook_Deactivate()
    Application.DisplayFullScreen = False
    Application.DisplayFormulaBar = True
End Sub

答案 2 :(得分:0)

您必须left join表上的EXT_DistributorFeedDetail才能提取serial列。请注意,对于输出中的每个recid,串行列将重复与EXT_DistributorFeedDetail表中每个linkid的条目数一样多次。

    WITH feedInfo AS 
    (
    SELECT df1.RecID, MfgPN, LinkID, ShipQuantity, 1 AS Number 
    FROM EXT_DistributorFeed df1
    WHERE df1.mfgPN IN ('ABC1', 'ABC2')  

    UNION ALL

    SELECT df2.RecID, df2.MfgPN, df2.LinkID, df2.ShipQuantity, 
    feedInfo.number + 1 AS Number 
    FROM EXT_DistributorFeed df2
    INNER JOIN feedInfo ON df2.RecID = feedInfo.RecID
    WHERE number < feedInfo.ShipQuantity
    AND df2.mfgPN IN ('ABC1', 'ABC2')
    )
    Select feedInfo.*, e.serial
    From feedInfo
    left join EXT_DistributorFeedDetail e
    on e.linkid = feedinfo.linkid