當前位置:
首頁 >
SQL递归
發布時間:2025/3/17
18
豆豆
我們先導入測試數據:
CREATE TABLE [dbo].[TestWithTable]([id] [int] IDENTITY(1,1) NOT NULL,[parentid] [int] NOT NULL,[name] [nchar](10) NULL,CONSTRAINT [PK_TestWithTable] 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]GO SET IDENTITY_INSERT [dbo].[TestWithTable] ON GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (1, 0, N'一級(1) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (2, 0, N'一級(2) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (3, 0, N'一級(3) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (4, 1, N'二級(1-1) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (5, 1, N'二級(1-2) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (6, 2, N'二級(2-1) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (7, 2, N'二級(2-2) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (8, 3, N'二級(3-1) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (9, 4, N'三級(1-1-1) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (10, 5, N'三級(1-2-1) ') GO INSERT [dbo].[TestWithTable] ([id], [parentid], [name]) VALUES (11, 7, N'三級(2-2-1) ') GO SET IDENTITY_INSERT [dbo].[TestWithTable] OFF GO ALTER TABLE [dbo].[TestWithTable] ADD CONSTRAINT [DF_TestWithTable_parentid] DEFAULT ((0)) FOR [parentid] GO接下來我們了解什么是WITH AS
WITH AS短語,也叫做子查詢部分(subquery factoring),可以定義一個SQL片斷,該SQL片斷會被整個SQL語句用到。可以使SQL語句的可讀性更高,也可以在UNION ALL的不同部分,作為提供數據的部分。
對于UNION ALL,使用WITH AS定義了一個UNION ALL語句,當該片斷被調用2次以上,優化器會自動將該WITH AS短語所獲取的數據放入一個Temp表中。而提示meterialize則是強制將WITH AS短語的數據放入一個全局臨時表中。很多查詢通過該方式都可以提高速度。
使用方法
我們先寫一個嵌套查詢,如下:
select * from TestWithTable where parentid in (1,7)我們再使用with as
with this_cts as ( select 1 as col union all select 7 as col ) select * from TestWithTable where parentid in (select * from this_cts)注意:
1.with as 后面必須要接上使用這個的查詢語句,否則這個cte不生效
2.如果使用多個with as ,那么使用逗號隔開
下面我們來使用遞歸
我們建表的目的就是建一個樹形結構,通過parentid找到它的父級,這里我們為了標注樹形結構使用'>|'符號分隔,每一個這個代表的一級,下面我們看代碼:
WITH TEST_CTE AS ( SELECT TBIE.id,TBIE.parentid,TBIE.name,cast( '>|' as nvarchar(1000)) as treeCode FROM TestWithTable TBIE WHERE TBIE.parentid = 0 UNION ALL SELECT CTBIE.id,CTBIE.parentid,CTBIE.name,cast( CTE.treeCode+'>|' as nvarchar(1000)) as treeCode FROM TestWithTable CTBIEINNER JOIN TEST_CTE CTE ON CTBIE.parentid=CTE.id ) SELECT * FROM TEST_CTE結果如下:
關于"在遞歸查詢 "TEST_CTE" 的列 "treeCode" 中,定位點類型和遞歸部分的類型不匹配。"
這個原因是因為在union 聯合查詢的時候,兩邊需要連接的表字段要求統一,所以把這個變化的列強轉成同一種類型即可
?
總結
- 上一篇: goim 中的 data flow 数据
- 下一篇: MySql error 2003 Can