通过SQL Server中的2个表进行递归选择

时间:2019-06-19 13:11:11

标签: sql sql-server reporting-services ssrs-2008

对于SSRS中的生产报告,我需要在我们的ERP中显示基础材料,该材料可以包含多个级别。

我在表INVENTPRODMETHOD中有项目,该项目的字段ProdMethodId与具有“支持项目”的INVENTPRODSUPPITEMS表相关。根据在第一张表中找到的ProdMethodId,我得到一个SUPPLITEMID,我需要在第一个表INVENTPRODMETHOD中找到该(新)项目的ProdMethodId,以此类推,等等。希望您能跟随我……

我的要求是,我需要了解最低级别的基础材料。例如:

我想找到项目100的基础材料。在DMO_INVENTPRODMETHOD表中,我可以看到PRODMETHODID = A123

在DMO_INVENTPRODSUPPITEMS中,它告诉我该PRODMETHODID A123的SUPPLITEMID为S200

现在我需要做同样的事情,但现在是S200。在DMO_INVENTPRODMETHOD中,当我在DMO_INVENTPRODSUPPITEMS中查找SUPPLITEMID为S400时,我得到PRODMETHODID E123

DMO_INVENTPRODMETHOD中的S400具有PRODMETHODID Z123,但是PROMOETHODID在DMO_INVENTPRODSUPPITEMS中不存在

现在我知道我需要在具有PRODMETHODID Z123的DMO_INVENTPRODBASEITEMS表中查找ITEMID

CREATE TABLE DMO_INVENTPRODMETHOD (
    ITEMID VARCHAR (10) NOT NULL,
    PRODMETHODID VARCHAR (10) NOT NULL,
);

INSERT INTO [dbo].[DMO_INVENTPRODMETHOD] VALUES ('100', 'A123')
INSERT INTO [dbo].[DMO_INVENTPRODMETHOD] VALUES ('S200', 'E123')
INSERT INTO [dbo].[DMO_INVENTPRODMETHOD] VALUES ('S400', 'Z123')



CREATE TABLE DMO_INVENTPRODSUPPITEMS (
    SUPPLITEMID VARCHAR (10) NOT NULL,
    PRODMETHODID VARCHAR (10) NOT NULL,
);

INSERT INTO [dbo].[DMO_INVENTPRODSUPPITEMS] VALUES ('S200', 'A123')
INSERT INTO [dbo].[DMO_INVENTPRODSUPPITEMS] VALUES ('S400', 'E123')


CREATE TABLE DMO_INVENTPRODBASEITEMS (
    ITEMID VARCHAR (10) NOT NULL,
    PRODMETHODID VARCHAR (10) NOT NULL,
);
INSERT INTO [dbo].[DMO_INVENTPRODBASEITEMS] VALUES ('BAAAB10', 'Z123')

迈克

1 个答案:

答案 0 :(得分:2)

这是解决此问题的一种方法。

首先,将值归一化为父/子表。接下来,对标准化数据执行相当标准的递归cte。最后,按相反​​的顺序获取链中的最后一个后代。

Sql Fiddle

DECLARE @DMO_INVENTPRODMETHOD  TABLE(ITEMID  VARCHAR (10) NOT NULL,PRODMETHODID VARCHAR (10) NOT NULL)
INSERT INTO @DMO_INVENTPRODMETHOD VALUES ('100', 'A123'),('S200', 'E123'),('S400', 'Z123')

DECLARE @DMO_INVENTPRODSUPPITEMS TABLE(SUPPLITEMID  VARCHAR (10) NOT NULL,PRODMETHODID  VARCHAR (10) NOT NULL)
INSERT INTO @DMO_INVENTPRODSUPPITEMS VALUES ('S200', 'A123'),('S400', 'E123')

DECLARE @DMO_INVENTPRODBASEITEMS TABLE(ITEMID VARCHAR (10) NOT NULL,PRODMETHODID VARCHAR (10) NOT NULL)
INSERT INTO @DMO_INVENTPRODBASEITEMS VALUES ('BAAAB10', 'Z123')

DECLARE @ITEMID NVARCHAR(10) = '100'

;WITH CombinedData AS
(
    SELECT DataLevel=1, ParentID=ITEMID, ChildID=PRODMETHODID  FROM @DMO_INVENTPRODMETHOD
    UNION
    SELECT DataLevel=2, ParentID=PRODMETHODID ,ChildID=SUPPLITEMID  FROM @DMO_INVENTPRODSUPPITEMS
    UNION
    SELECT DataLevel=3, ParentID=PRODMETHODID ,ChildID=ITEMID  FROM @DMO_INVENTPRODBASEITEMS
) 
,RecursiveWalk AS
 (
    SELECT  ParentID, ChildID,Level=1 FROM CombinedData WHERE  DataLevel=1 AND ParentID=@ITEMID

    UNION ALL

    SELECT D.ParentID,D.ChildID, Level=R.Level+1
    FROM
        RecursiveWalk R
        INNER JOIN  CombinedData D ON D.ParentID=R.ChildID
)
,ResultReverseOrdered AS
(
    SELECT *, RowNumber = ROW_NUMBER() OVER(ORDER BY Level DESC) FROM RecursiveWalk
)
SELECT
    PRODMETHODID = ParentID,
    Level 
FROM    
    ResultReverseOrdered
WHERE
    RowNumber = 1