postgresql 省市区为例-递归查询

一,创建示例表,创建示例数据

本来想把全国所有省市区地址都写上,但是内容字数超长,

如果需要详细全部省市区数据的请自行下载:https://download.csdn.net/download/qq_37519791/14884271

CREATE TABLE why_c_p_c_d(
adcode varchar(16),
name varchar(16),
parent_id varchar(16)
);
INSERT INTO "public"."why_c_p_c_d" VALUES ('100000', '中华人民共和国', '0');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510000', '四川省', '100000');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510800', '广元市', '510000');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510811', '昭化区', '510800');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510812', '朝天区', '510800');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510823', '剑阁县', '510800');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510824', '苍溪县', '510800');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510821', '旺苍县', '510800');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510822', '青川县', '510800');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510802', '利州区', '510800');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510100', '成都市', '510000');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510182', '彭州市', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510113', '青白江区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510129', '大邑县', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510181', '都江堰市', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510184', '崇州市', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510185', '简阳市', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510131', '蒲江县', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510118', '新津区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510121', '金堂县', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510183', '邛崃市', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510115', '温江区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510116', '双流区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510117', '郫都区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510107', '武侯区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510106', '金牛区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510112', '龙泉驿区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510114', '新都区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510108', '成华区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510104', '锦江区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510105', '青羊区', '510100');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510700', '绵阳市', '510000');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510722', '三台县', '510700');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510725', '梓潼县', '510700');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510704', '游仙区', '510700');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510781', '江油市', '510700');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510727', '平武县', '510700');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510723', '盐亭县', '510700');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510703', '涪城区', '510700');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510705', '安州区', '510700');
INSERT INTO "public"."why_c_p_c_d" VALUES ('510726', '北川羌族自治县', '510700');


二、示例查询语句


select * from why_c_p_c_d  order by adcode

-- 原理
-- 把 SELECT adcode, name, parent_id FROM why_c_p_c_d WHERE adcode = '510000' 查询结果作为第一次的值
-- 然后开始以 SELECT e.adcode, e.name, e.parent_id FROM why_c_p_c_d e INNER JOIN results s ON s.adcode = e.parent_id 作为依据开始循环
-- UNION 或者 UNION ALL 后面的每次范围结果作为下一次的条件值,依次递归就可以查出所有父级或者子级
-- 根据主adcode 查询所有子级
WITH RECURSIVE results AS (
   SELECT adcode, name, parent_id, 1 AS level FROM why_c_p_c_d WHERE adcode = '510000'
   UNION
   SELECT e.adcode, e.name, e.parent_id,s.Level+1 AS Level  FROM why_c_p_c_d as e
   INNER JOIN results as s ON s.adcode = e.parent_id
) SELECT * FROM results order by adcode;

--根据子id查询所有父级
WITH RECURSIVE results AS (
   SELECT adcode, name, parent_id FROM why_c_p_c_d WHERE adcode = '510107'
   UNION
   SELECT e.adcode, e.name, e.parent_id FROM why_c_p_c_d as e
   INNER JOIN results as s ON s.parent_id = e.adcode
) SELECT * FROM results order by adcode;


WITH RECURSIVE results AS (
   SELECT adcode, name, parent_id, 1 AS level FROM why_c_p_c_d WHERE adcode = '510000'
   UNION
   SELECT e.adcode, e.name, e.parent_id,s.Level+1 AS Level  FROM why_c_p_c_d as e
   INNER JOIN results as s ON s.adcode = e.parent_id
)
SELECT 
    t1.name as 一级,t2.name as 二级,t3.name as 三级
FROM 
(SELECT * FROM results WHERE LEVEL=1) AS t1
INNER JOIN 
(SELECT * FROM results WHERE LEVEL=2) AS t2 ON t1.adcode=t2.parent_id
INNER JOIN
(SELECT * FROM results WHERE LEVEL=3) AS t3 ON t2.adcode=t3.parent_id
ORDER BY 1,2,3;

 

 

你可能感兴趣的:(postgresql)