我的应用程序读取具有父子关系的表。应用程序自己查询树的每个级别,它确实很慢(必须深入多个级别)。我已经搜索了另一个解决方案并进入了递归查询。通过我发现的示例,我无法将其映射到我的数据结构。
我的结构如下:
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]
当我查询parentNumber 1时,它应该给我所有这些行:
现在我需要父母的所有孩子以递归的方式。我怎样才能使用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 :(得分: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]
;