Create table #country (AreaNam NVARCHAR(10),BelongTo Nvarchar(10),Msg varchar(100))
下面我們往這張表裏插入一堆測試數據:
INSERT INTO #country
SELECT '中國','中國',null union all
SELECT '江蘇','中國',null union all
SELECT '南京','江蘇',null union all
SELECT '無錫','江蘇',null union all
SELECT '徐州','江蘇',null union all
SELECT '揚州','江蘇',null union all
SELECT '蘇州','江蘇',null union all
SELECT '六合區','南京',null union all
SELECT '江寧區','南京',null union all
SELECT '浦口區','南京',null union all
SELECT '仙林區','南京',null union all
SELECT '建鄴區','南京',null union all
SELECT '寶應','揚州',null union all
SELECT '儀徵','揚州',null union all
SELECT '小官莊','寶應',null union all
SELECT '範水','寶應',null union all
SELECT '魯垛','寶應',null union all
SELECT '安宜','寶應',null union all
SELECT '組全','小官莊',null union all
SELECT '房橋','小官莊',null union all
SELECT '直下溝','小官莊',null union all
SELECT '山東','中國',null union all
SELECT '濟南','山東',null union all
SELECT '青島','山東',null union all
SELECT '淄博','山東',null union all
SELECT '煙臺','山東',null union all
SELECT '張店','淄博',null union all
SELECT '博山','淄博',null union all
SELECT '淄川','淄博',null union all
SELECT '龍王山','浦口區',null union all
SELECT '高新區','浦口區',null union all
SELECT '陸軍指揮學院','浦口區',null union all
SELECT '南京信息工程大學','浦口區',null union all
SELECT '金陵學院','浦口區',null
到這裏,表結構已經完成了,這張表的表結構應該不難理解。
但是下面問題來了,有要求查找出南京包含南京以內(屬於南京)的所有地名,因爲如果數據量比較大的話,我們根本無法確定一個城市往下分了多少級地名,如果分的層級太多的話,使用循環取實現查詢結果也是一個可行的方案,sql如下:
DECLARE @CITY NVARCHAR(MAX)='南京'
Create table #TEMP (AreaNam NVARCHAR(10),BelongTo Nvarchar(10),Msg varchar(100))
Create table #tempAreaname (AreaNam NVARCHAR(10))
Create table #tempAreanametemp (AreaNam NVARCHAR(10))
INSERT INTO #tempAreaname
SELECT @CITY
INSERT INTO #TEMP
SELECT * FROM #country WHERE AreaNam=@CITY
WHILE 1=1
BEGIN
insert into #tempAreanametemp
SELECT areanam FROM #country WHERE belongto IN(select areanam from #tempAreaname)
IF @@ROWCOUNT<>0
BEGIN
INSERT INTO #TEMP
SELECT * FROM #country WHERE belongto IN(select areanam from #tempAreaname)
delete from #tempAreaname
insert into #tempAreaname
select * from #tempAreanametemp
delete from #tempAreanametemp
END
ELSE
BEGIN
SELECT * FROM #TEMP
DROP TABLE #TEMP
DROP TABLE #tempAreaname
DROP TABLE #tempAreanametemp
RETURN
END
END
查詢結果如下:
AreaNam BelongTo Msg
南京 江蘇 NULL
六合區 南京 NULL
江寧區 南京 NULL
浦口區 南京 NULL
仙林區 南京 NULL
建鄴區 南京 NULL
龍王山 浦口區 NULL
高新區 浦口區 NULL
陸軍指揮學院 浦口區 NULL
南京信息工程大學 浦口區 NULL
金陵學院 浦口區 NULL
這正是我們所想要的結果,但是總感覺這寫法太複雜而且執行效率也不是很高,當然啦用循環去寫的話肯定也有簡單一點的寫法的,這不是我們今天的重點。今天的重點是用CTE遞歸的方式去實現我們所想要的結果,SQL如下:
WITH CTE AS (
SELECT AreaNam,BelongTo,Msg FROM #country WHERE AreaNam='南京'
UNION ALL
SELECT A.AreaNam,A.BelongTo,A.Msg FROM #country A INNER JOIN CTE B ON A.BelongTo=B.AreaNam
)
SELECT * FROM CTE
查詢結果也是一樣一樣的:
AreaNam BelongTo Msg
南京 江蘇 NULL
六合區 南京 NULL
江寧區 南京 NULL
浦口區 南京 NULL
仙林區 南京 NULL
建鄴區 南京 NULL
龍王山 浦口區 NULL
高新區 浦口區 NULL
陸軍指揮學院 浦口區 NULL
南京信息工程大學 浦口區 NULL
金陵學院 浦口區 NULL