https://www.cnblogs.com/lonelyxmas/p/10652423.html
最近在轉.net, 需要做一個導航欄的功能, 這裏記錄下通過sql直接遞歸實現查詢某個導航下面所有文章的sql語句
SQL SERVER 2005之前的版本只能用函數方法實現,SQL SERVER 2005之後新增了CTE功能,可以利用CTE實現遞歸查詢;
CTE:公用表達式Common Table Expression 是SQL SERVER 2005版本之後引入的一個特性;
分類表和文章表 表結構
分類表結構
Id | int |
Pid | int |
Name | nvarchar(256) |
Sort | int |
SeoTitle | nvarchar(256) |
SeoKeyword | nvarchar(MAX) |
SeoDesc | nvarchar(MAX) |
CreateTime | datetime |
分類表內容
文章表結構
Id | |
CategoryId | |
Title | |
[Content] | |
Sort | |
SeoTitle | |
SeoKeyword | |
SeoDesc | |
CreateTime | |
UpdateTime |
解釋
裏面 域名/企訊網/財務相關/全網營銷產品/朝陽企訊通APP/售後服務 是頂級分類:
問題:
1 查詢頂級分類下的所有文章, 注意 Pid=0/第四行中 on c.pid=t.id
-- 使用臨時表,遞歸查詢導航下的所有分級導航
with temp as(
select * from DocCate where Pid=0
union all
select c.* from DocCate c join temp t on c.pid=t.id)
select temp.Id,temp.Name into #Temp11221 from temp
-- 分頁查詢所有導航下的文章, 掠過0條取出10條
select #Temp11221.Name as CategoryName,DocInfo.* from DocInfo join #Temp11221 on DocInfo.CategoryId = #Temp11221.Id
order by Sort
offset 0 rows fetch next 10 rows only
-- 查詢該導航下所有文章數量
select Count(1) from DocInfo join #Temp11221 on DocInfo.CategoryId = #Temp11221.Id
-- 刪除臨時表
if object_id('tempdb..#Temp11221') is not null Begin
drop table #Temp11221
End
2 查詢非頂級分類下的所有文章, 注意 id=13/第四行中 on c.pid=t.id
-- 使用臨時表,遞歸查詢導航下的所有分級導航
with temp as(
select * from DocCate where id=13
union all
select c.* from DocCate c join temp t on c.pid=t.id)
select temp.Id,temp.Name into #Temp11221 from temp
-- 分頁查詢所有導航下的文章, 掠過0條取出10條
select #Temp11221.Name as CategoryName,DocInfo.* from DocInfo join #Temp11221 on DocInfo.CategoryId = #Temp11221.Id
order by Sort
offset 0 rows fetch next 10 rows only
-- 查詢該導航下所有文章數量
select Count(1) from DocInfo join #Temp11221 on DocInfo.CategoryId = #Temp11221.Id
-- 刪除臨時表
if object_id('tempdb..#Temp11221') is not null Begin
drop table #Temp11221
End
3/查詢分類(頂級/非頂級)之前的分類 , 逆向遞歸查詢
-- 使用臨時表,遞歸查詢導航下的所有分級導航
with temp as(
select * from DocCate where id=16
union all
select c.* from DocCate c join temp t on c.id=t.pid)
select temp.Id,temp.Name into #Temp11221 from temp
-- 分頁查詢所有導航下的文章, 掠過0條取出10條
select * from #Temp11221
-- 刪除臨時表
if object_id('tempdb..#Temp11221') is not null Begin
drop table #Temp11221
End