我有两张SQL Server桌子:
invoice)invoice_relation)invoice table存储具有事务作品集的所有发票记录.
invoice_relation 表存储发票之间的任何关系.
这是发票如何相互关联的示例:
所以,我们的目标是找到" folio"下invoice表中给出的invoicenumber和folio,但folio有时不会是folio了invoice了,所以我需要做的,为了所有的树关系的搜索找到,如果任何发票匹配发票号码但也是folio这种关系的一部分.
例如,我必须找到对开的发票编号:
在我的查询中,我需要首先通过作品集找到因为它是我的invoice表主键.然后,将尝试匹配A1122与D1122该会不匹配,所以后来我搜索所有树结构发现,如果有一个A1122.结果将是A1122在对开页中找到发票1000.
有关如何做到这一点的任何线索?
这是一个如何使用数据创建上述示例表的脚本:
CREATE TABLE [dbo].[invoice](
[folio] [int] NOT NULL,
[invoicenumber] [nvarchar](20) NOT NULL,
[isactive] [bit] NOT NULL,
CONSTRAINT [PK_invoice] PRIMARY KEY CLUSTERED
(
[folio] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[invoice_relation](
[relationid] [int] NOT NULL,
[invoice] [nvarchar](20) NOT NULL,
[parentinvoice] [nvarchar](20) NOT NULL,
CONSTRAINT [PK_invoice_relation_1] PRIMARY KEY CLUSTERED
(
[relationid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[invoice] ([folio], [invoicenumber], [isactive]) VALUES (1000, N'A1122', 1)
GO
INSERT [dbo].[invoice] ([folio], [invoicenumber], [isactive]) VALUES (1001, N'B1122', 1)
GO
INSERT [dbo].[invoice] ([folio], [invoicenumber], [isactive]) VALUES (1002, N'C1122', 1)
GO
INSERT [dbo].[invoice] ([folio], [invoicenumber], [isactive]) VALUES (1003, N'D1122', 1)
GO
INSERT [dbo].[invoice] ([folio], [invoicenumber], [isactive]) VALUES (1004, N'F1122', 1)
GO
INSERT [dbo].[invoice] ([folio], [invoicenumber], [isactive]) VALUES (1005, N'G1122', 1)
GO
INSERT [dbo].[invoice_relation] ([relationid], [invoice], [parentinvoice]) VALUES (1, N'A1122', N'B1122')
GO
INSERT [dbo].[invoice_relation] ([relationid], [invoice], [parentinvoice]) VALUES (2, N'C1122', N'A1122')
GO
INSERT [dbo].[invoice_relation] ([relationid], [invoice], [parentinvoice]) VALUES (3, N'D1122', N'A1122')
GO
INSERT [dbo].[invoice_relation] ([relationid], [invoice], [parentinvoice]) VALUES (4, N'F1122', N'B1122')
GO
INSERT [dbo].[invoice_relation] ([relationid], [invoice], [parentinvoice]) VALUES (5, N'G1122', N'F1122')
GO
Run Code Online (Sandbox Code Playgroud)
这很棘手,因为您有一个单独的关系表,并且根发票不在其中。
DECLARE @folio INT = 1003,
@invoice NVARCHAR(20) = 'A1122'
-- find highest level of relationship
;WITH cte AS (
SELECT i.folio,
i.invoicenumber,
ir.parentinvoice,
0 AS [level]
FROM invoice i
LEFT JOIN invoice_relation ir ON ir.invoice = i.invoicenumber
WHERE i.folio = @folio
UNION ALL
SELECT i.folio,
i.invoicenumber,
ir.parentinvoice,
[level] + 1
FROM invoice i
JOIN invoice_relation ir ON ir.invoice = i.invoicenumber
JOIN cte r ON r.parentinvoice = i.invoicenumber
),
-- make sure you get the root folio
rootCte AS (
SELECT COALESCE(oa.folio, c.folio) AS rootFolio
FROM (SELECT *,
ROW_NUMBER() OVER (ORDER BY [level] DESC) Rn
FROM cte ) c
OUTER APPLY (SELECT folio FROM invoice i WHERE i.invoicenumber = c.parentinvoice) oa
WHERE c.Rn = 1
),
-- get all children of root folio
fullTree AS (
SELECT i.folio,
i.invoicenumber
FROM rootCte r
JOIN invoice i ON r.rootFolio = i.folio
UNION ALL
SELECT i.folio,
i.invoicenumber
FROM fullTree ft
JOIN invoice_relation ir ON ir.parentinvoice = ft.invoicenumber
JOIN invoice i ON ir.invoice = i.invoicenumber
)
-- search for invoice
SELECT *
FROM fullTree
WHERE invoicenumber = @invoice
Run Code Online (Sandbox Code Playgroud)