2017-03-16 32 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] 
;