通过 SQL 服务器中的 2 个表递归 select
Recursive select through 2 tables in SQL Server
对于 SSRS 中的生产报告,我需要在我们的 ERP 中显示基础 material,它可以包含多个级别。
我在 table INVENTPRODMETHOD 中有项目,其中有一个 ProdMethodId 字段,这与 table 和 'supporting items' 的 INVENTPRODSUPPITEMS 相关。基于在第一个 table 中找到的 ProdMethodId,我得到一个 SUPPLITEMID,我需要找出这个(新)项目的 ProdMethodId 在第一个 table INVENTPRODMETHOD 等中。希望你能跟我来…
我的要求是我需要知道最低级别的基础material。例如:
我想找到项目 100 的基础 material。在 DMO_INVENTPRODMETHOD table 中,我可以看到 PRODMETHODID = A123
在 DMO_INVENTPRODSUPPITEMS 它告诉我这个 PRODMETHODID A123 有一个 S200 的 SUPPLITEMID
现在我需要做同样的事情,但现在是 S200。在 DMO_INVENTPRODMETHOD 中,当我在 DMO_INVENTPRODSUPPITEMS 中查找时,我得到了 PRODMETHODID E123,SUPPLITEMID 是 S400
DMO_INVENTPRODMETHOD 中的 S400 具有 PRODMETHODID Z123,但 DMO_INVENTPRODSUPPITEMS
中不存在该 PRODMETHODID
现在我知道我需要使用 PRODMETHODID Z123
在 DMO_INVENTPRODBASEITEMS table 中查找 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')
麦克
这是解决此问题的一种方法。
首先,将值规范化为 Parent/Child table。接下来,对标准化数据执行非常标准的递归 cte。最后逆序得到链中的最后一个后代。
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
对于 SSRS 中的生产报告,我需要在我们的 ERP 中显示基础 material,它可以包含多个级别。
我在 table INVENTPRODMETHOD 中有项目,其中有一个 ProdMethodId 字段,这与 table 和 'supporting items' 的 INVENTPRODSUPPITEMS 相关。基于在第一个 table 中找到的 ProdMethodId,我得到一个 SUPPLITEMID,我需要找出这个(新)项目的 ProdMethodId 在第一个 table INVENTPRODMETHOD 等中。希望你能跟我来…
我的要求是我需要知道最低级别的基础material。例如:
我想找到项目 100 的基础 material。在 DMO_INVENTPRODMETHOD table 中,我可以看到 PRODMETHODID = A123
在 DMO_INVENTPRODSUPPITEMS 它告诉我这个 PRODMETHODID A123 有一个 S200 的 SUPPLITEMID
现在我需要做同样的事情,但现在是 S200。在 DMO_INVENTPRODMETHOD 中,当我在 DMO_INVENTPRODSUPPITEMS 中查找时,我得到了 PRODMETHODID E123,SUPPLITEMID 是 S400
DMO_INVENTPRODMETHOD 中的 S400 具有 PRODMETHODID Z123,但 DMO_INVENTPRODSUPPITEMS
中不存在该 PRODMETHODID现在我知道我需要使用 PRODMETHODID Z123
在 DMO_INVENTPRODBASEITEMS table 中查找 ITEMIDCREATE 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')
麦克
这是解决此问题的一种方法。
首先,将值规范化为 Parent/Child table。接下来,对标准化数据执行非常标准的递归 cte。最后逆序得到链中的最后一个后代。
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