2017-03-16 50 views
-1

我的应用程序使用父子关系读取一个表。应用程序自己查询树的每个级别,并且它确实很慢(必须深入多级)。我正在寻找另一个解决方案并来到递归查询。用我发现的例子,我不能将它映射到我的数据结构。递归查询以加快系统的速度

我的结构是这样的:

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 
+0

您不应该一次获取所有内容。您需要一次加载所需的唯一数据。即使您通过递归查询来获取所有数据,从SQL Server转移到Application也是非常重要的。该应用程序也可能变得无法响应。 – Venu

+0

无响应在我的应用程序设置中不是问题。查询在服务器端完成,客户端只需等待他的答案。我需要将所有数据展示给用户。 – JimmyD

+0

以文本格式发布表格结构,样本数据和预期输出。看看[这里](https://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/)关于如何在论坛发布sql问题。 – Venu

回答

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] 
;