国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PostgreSQL:遞歸查詢應(yīng)用場(chǎng)景

YJNldm / 2813人閱讀

摘要:今天在壇子里有人提出了一個(gè)問題,問題是這樣的在以下指定表中中國(guó)遼寧山東沈陽大連濟(jì)南和平區(qū)沈河區(qū)現(xiàn)在給定一個(gè)號(hào),想得到它完整的名字。遞歸往上找,直到為止。也就是最高層級(jí)時(shí)結(jié)束,求完整語句。

今天在壇子里有人提出了一個(gè)問題,問題是這樣的:在以下指定表中

id name fatherid
1 中國(guó) 0
2 遼寧 1
3 山東 1
4 沈陽 2
5 大連 2
6 濟(jì)南 3
7 和平區(qū) 4
8 沈河區(qū) 4

現(xiàn)在給定一個(gè)id號(hào),想得到它完整的名字。如:
當(dāng)id=7時(shí),名字是:中國(guó)遼寧沈陽和平區(qū)
當(dāng)id=5時(shí),名字是:中國(guó)遼寧大連

id是任意給定的,不確定在哪一層。遞歸往上找,直到 fatherid=0 為止。也就是最高層級(jí)時(shí)結(jié)束,
求完整SQL語句。

看到這個(gè)問題,第一想到的是可以用 PG的遞歸查詢實(shí)現(xiàn),之前也寫過類似的例子,
http://francs3.blog.163.com/b...,但之前的例子
是向下遞歸,而這里的需求是向上遞歸,略有不同,于是忍不住演示下:

這個(gè)問題的思路是分兩步走,第一步:查詢出指定節(jié)點(diǎn)的父節(jié)點(diǎn);第二步:將查詢出的所有父節(jié)點(diǎn)排列到一行。

--1 創(chuàng)建測(cè)試表,并插入測(cè)試數(shù)據(jù)

skytf=> create table test_area(id int4,name varchar(32),fatherid int4);
CREATE TABLE

insert into test_area values (1, "中國(guó)"   ,0);
insert into test_area values (2, "遼寧"   ,1);
insert into test_area values (3, "山東"   ,1);
insert into test_area values (4, "沈陽"   ,2);
insert into test_area values (5, "大連"   ,2);
insert into test_area values (6, "濟(jì)南"   ,3);
insert into test_area values (7, "和平區(qū)" ,4);
insert into test_area values (8, "沈河區(qū)" ,4);
skytf=> select * From test_area;
 id |  name  | fatherid 
----+--------+----------
  1 | 中國(guó)   |        0
  2 | 遼寧   |        1
  3 | 山東   |        1
  4 | 沈陽   |        2
  5 | 大連   |        2
  6 | 濟(jì)南   |        3
  7 | 和平區(qū) |        4
  8 | 沈河區(qū) |        4
(8 rows)

--2 查詢指定節(jié)點(diǎn)以下的所有節(jié)點(diǎn)

  WITH RECURSIVE r AS ( 

       SELECT * FROM test_area WHERE id = 4 
     union   ALL 
       SELECT test_area.* FROM test_area, r WHERE test_area.fatherid = r.id 
     ) 
SELECT * FROM r ORDER BY id;
 id |  name  | fatherid 
----+--------+----------
  4 | 沈陽   |        2
  7 | 和平區(qū) |        4
  8 | 沈河區(qū) |        4
(3 rows)

備注:通常的用法是查詢指定節(jié)點(diǎn)以及指定節(jié)點(diǎn)以下的所有節(jié)點(diǎn),那么本貼的需求剛好相反,需要查詢指定節(jié)點(diǎn)以上的所有節(jié)點(diǎn)。

--3 查詢指定節(jié)點(diǎn)以上的所有節(jié)點(diǎn)

 WITH RECURSIVE r AS ( 
       SELECT * FROM test_area WHERE id = 4 
     union   ALL 
       SELECT test_area.* FROM test_area, r WHERE test_area.id = r.fatherid 
     ) 
 SELECT * FROM r ORDER BY id;

 id | name | fatherid 
----+------+----------
  1 | 中國(guó) |        0
  2 | 遼寧 |        1
  4 | 沈陽 |        2
(3 rows)

備注:這正是我們想要的結(jié)果,接下來需要將 name 字段結(jié)果集合并成一行,我這里想到的是創(chuàng)建個(gè) function,當(dāng)然也有其它方法。

--4 create funcion

CREATE or replace FUNCTION func_get_area(in in_id int4, out o_area text)  AS 

$$ 
DECLARE
   v_rec_record RECORD;
BEGIN

  o_area = "";
  FOR v_rec_record IN (WITH RECURSIVE r AS (SELECT *
                           FROM test_area
                          WHERE id = in_id
                         union ALL
                         SELECT test_area.*
                           FROM test_area, r
                          WHERE test_area.id = r.fatherid)SELECT name
                         FROM r
                        ORDER BY id) LOOP
    o_area := o_area || v_rec_record.name;
  END LOOP;
  return;
END; 
$$
LANGUAGE "plpgsql";

備注:函數(shù)的作用為拼接 name 字段。

--5 測(cè)試

 skytf=> select func_get_area(7) ;
   func_get_area    
--------------------
 中國(guó)遼寧沈陽和平區(qū)
(1 row)

skytf=> select func_get_area(5) ;
 func_get_area 
---------------
 中國(guó)遼寧大連
(1 row)

備注:正好實(shí)現(xiàn)了需求,當(dāng)表數(shù)據(jù)量較大時(shí),考慮到性能,建議在表 test_area 字段 id,fatherid 上建立多帶帶的索引。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/38974.html

相關(guān)文章

  • 我對(duì)Postgresql遞歸查詢的理解

    摘要:先聲明,瞎猜的,個(gè)人理解,不一定對(duì)。重復(fù)執(zhí)行步驟和,只是這里執(zhí)行第步的時(shí)候,從中選出的記錄為執(zhí)行第步,就變成了,就變成了找的兒子記錄如果第步返回多條記錄,類似啦,反正遞歸嘛如此,自頂向下,一棵樹就出來了 先聲明,瞎猜的,個(gè)人理解,不一定對(duì)。 遞歸查詢大家都知道,常見的如一張表,包含id(主鍵),parent_id(該記錄的父親id),比如我們要從某1個(gè)id往下找他所有的兒子還有孫子(這...

    kaka 評(píng)論0 收藏0
  • PostgreSQL UDB,讓31會(huì)議數(shù)據(jù)管理更高效可靠

    摘要:相比自建,其可靠性更高,方便運(yùn)維維護(hù)。宋體經(jīng)過審慎考慮,用戶同時(shí)選用三種數(shù)據(jù)庫(kù),針對(duì)性的滿足不同目標(biāo)。宋體宋體其中,相比于在上的快速高效是其優(yōu)勢(shì),也是用戶選型的重要砝碼。PostgreSQL UDB用在大數(shù)據(jù)分析上,查詢效率更高。相比自建,其可靠性更高,方便運(yùn)維維護(hù)。 — 31會(huì)議運(yùn)維經(jīng)理 湯雷 如何用好PostgreSQL? PostgreSQL是業(yè)內(nèi)一款十分流行的開源數(shù)...

    vspiders 評(píng)論0 收藏0
  • 構(gòu)建可擴(kuò)展的PostgreSQL解決方案

    摘要:這可以通過負(fù)載平衡來實(shí)現(xiàn)數(shù)據(jù)分片當(dāng)問題不是并發(fā)查詢的數(shù)量,而是數(shù)據(jù)庫(kù)的大小和單個(gè)查詢的速度時(shí),可以實(shí)現(xiàn)不同的方法。 showImg(https://segmentfault.com/img/remote/1460000018875091); 來源 | 愿碼(ChainDesk.CN)內(nèi)容編輯 愿碼Slogan | 連接每個(gè)程序員的故事 網(wǎng)站 | http://chaindesk.cn...

    jonh_felix 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<