2017-03-16 7 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からアプリケーションに転送するのは膨大です。アプリケーションも応答しなくなる可能性があります。 – Venu

+0

私のアプリケーションのセットアップでは、応答しないことは問題ではありません。クエリはサーバー側で実行され、クライアントは単に彼の答えを待つ必要があります。私はユーザーに示すためにすべてのデータが必要です。 – JimmyD

+0

テーブル構造、サンプルデータ、および予想される出力をテキスト形式で送信します。フォーラムにSQL質問を投稿する方法については、[こちら](https://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/)をご覧ください。 – 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] 
; 
関連する問題