递归查询以加速系统

时间:2017-03-16 07:39:34

标签: sql sql-server recursive-query

我的应用程序读取具有父子关系的表。应用程序自己查询树的每个级别,它确实很慢(必须深入多个级别)。我已经搜索了另一个解决方案并进入了递归查询。通过我发现的示例,我无法将其映射到我的数据结构。

我的结构如下:

CREATE TABLE [products].[BillOfMaterial](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [parentNumber] [nvarchar](50) NOT NULL,
    [warehouse] [nvarchar](50) NOT NULL,
    [sequenceNumber] [int] NOT NULL,
    [childNumber] [nvarchar](50) NOT NULL,
    [childDescription] [nvarchar](50) NULL,
    [qtyRequired] [numeric](18, 3) NOT NULL,
    [childItemClass] [nvarchar](50) NULL,
    [childItemType] [nvarchar](50) NULL,
    [scrapFactor] [numeric](18, 3) NULL,
    [bubbleNumber] [int] NOT NULL,
    [operationNumber] [int] NOT NULL,
    [effectivityDate] [date] NULL,
    [discontinuityDate] [date] NULL,
    [companyID] [bigint] NOT NULL,
 CONSTRAINT [PK_BillOfMaterial] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

一些示例数据:
enter image description here

当我查询parentNumber 1时,它应该给我所有这些行: enter image description here

对于parentNumber 3,输出必须是:
enter image description here

现在我需要父母的所有孩子以递归的方式。我怎样才能使用sql实现这一点? (我正在使用SQL服务器)

我已尝试在sql中使用with语句,但它现在会产生很多结果。

WITH bom ( [id]
      ,[parentNumber]
      ,[warehouse]
      ,[sequenceNumber]
      ,[childNumber]
      ,[childDescription]
      ,[qtyRequired]
      ,[childItemClass]
      ,[childItemType]
      ,[scrapFactor]
      ,[bubbleNumber]
      ,[operationNumber]
      ,[effectivityDate]
      ,[discontinuityDate]
      ,[companyID] )
AS
(
    select * from [CR_ApplicationSuite].[products].[BillOfMaterial] where parentNumber IN ('F611882261', '2912435206')
UNION ALL
select b.* from [CR_ApplicationSuite].[products].[BillOfMaterial] b
INNER JOIN [CR_ApplicationSuite].[products].[BillOfMaterial] c on c.childNumber = b.parentNumber
)
SELECT *
FROM bom

1 个答案:

答案 0 :(得分:1)

这是一个使用表变量进行演示的示例。

对于递归查询,您需要在其自身内使用CTE。

我包含了一个rootParentNumber,因此基本父母的内容更为明显。

示例中注释了WHERE子句。 因为您可以在递归查询中或外部查询中放置WHERE子句。前者应该更快。

declare @BillOfMaterial  TABLE (
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [parentNumber] [nvarchar](50) NOT NULL,
    [warehouse] [nvarchar](50) NOT NULL,
    [sequenceNumber] [int] NOT NULL,
    [childNumber] [nvarchar](50) NOT NULL,
    [childDescription] [nvarchar](50) NULL,
    [qtyRequired] [numeric](18, 3) NOT NULL,
    [childItemClass] [nvarchar](50) NULL,
    [childItemType] [nvarchar](50) NULL,
    [scrapFactor] [numeric](18, 3) NULL,
    [bubbleNumber] [int] NOT NULL,
    [operationNumber] [int] NOT NULL,
    [effectivityDate] [date] NULL,
    [discontinuityDate] [date] NULL,
    [companyID] [bigint] NOT NULL
);

insert into @BillOfMaterial (parentNumber, childNumber, warehouse, sequenceNumber, qtyRequired, bubbleNumber, operationNumber, companyID) values
('1','2','WH1',1,0,0,0,1),
('2','4','WH1',2,0,0,0,1),
('3','4','WH1',3,0,0,0,1),
('4','5','WH1',4,0,0,0,1),
('5','0','WH1',5,0,0,0,1);

WITH BOM 
AS
(
    select parentNumber as rootParentNumber, * 
    from @BillOfMaterial 
    --where parentNumber IN ('1','3')

    union all

    select bom.rootParentNumber, b.* 
    from BOM
    INNER JOIN @BillOfMaterial b 
    on (BOM.childNumber = b.parentNumber and b.childNumber <> '0')
)
SELECT 
 [rootParentNumber]
,[parentNumber]
,[childNumber]
,[id]
,[warehouse]
,[sequenceNumber]
,[childDescription]
,[qtyRequired]
,[childItemClass]
,[childItemType]
,[scrapFactor]
,[bubbleNumber]
,[operationNumber]
,[effectivityDate]
,[discontinuityDate]
,[companyID]
FROM BOM
--WHERE rootParentNumber IN ('1','3')
ORDER BY [rootParentNumber], [parentNumber], [childNumber]
;