| 1 | = Recursive query to find duplicates = |
| 2 | |
| 3 | |
| 4 | {{{#!sql |
| 5 | |
| 6 | /* |
| 7 | Dans la récurisve ci dessous la premire partie cree un tableau avec (id1 id2 s_bruto) |
| 8 | Ou les id1 sont à moins de xx m de distance de id2 |
| 9 | Plusieurs ouvrages peuvent être à distance proche... |
| 10 | |
| 11 | Dans la deuxième partie, récursive, (search_path est la vraie récursive mais il faut mettre récursive en tête) |
| 12 | on fait une jointure entre id2 et id1 qui s'arrête quand il n'y a plus de lien. Cet arrêt est dans la colonne cycle. |
| 13 | Un petit truc que j'ai mis du temps à trouver c'est le ::text, sinon j'avais des incompatible type character varying 10 |
| 14 | et charcater varying, et si j'essayais de caster en character varying je perdais array, et si j'assayais character varying[] ça |
| 15 | marchait pas... |
| 16 | |
| 17 | Ci dessous il y a plusieurs niveaux d'agréggation, par exemple chain5_et_ses_petits correspond à |
| 18 | id1;id2;sbruto_m;depth;path |
| 19 | SO_180;SO_181;;5;{SO_188,SO_187,SO_183,SO_181,SO_180} |
| 20 | SO_180;SO_181;;4;{SO_187,SO_183,SO_181,SO_180} |
| 21 | SO_181;SO_183;;4;{SO_188,SO_187,SO_183,SO_181} |
| 22 | SO_180;SO_183;;4;{SO_188,SO_187,SO_183,SO_180} |
| 23 | SO_180;SO_181;;4;{SO_187,SO_183,SO_181,SO_180} |
| 24 | SO_180;SO_181;;4;{SO_188,SO_183,SO_181,SO_180} |
| 25 | SO_180;SO_181;;4;{SO_188,SO_187,SO_181,SO_180} |
| 26 | SO_180;SO_183;;3;{SO_187,SO_183,SO_180} |
| 27 | SO_180;SO_181;;3;{SO_187,SO_181,SO_180} |
| 28 | SO_183;SO_187;;3;{SO_188,SO_187,SO_183} |
| 29 | SO_181;SO_187;;3;{SO_188,SO_187,SO_181} |
| 30 | SO_180;SO_187;;3;{SO_188,SO_187,SO_180} |
| 31 | SO_181;SO_183;;3;{SO_188,SO_183,SO_181} |
| 32 | SO_180;SO_183;;3;{SO_188,SO_183,SO_180} |
| 33 | SO_180;SO_181;;3;{SO_188,SO_181,SO_180} |
| 34 | SO_180;SO_181;;3;{SO_183,SO_181,SO_180} |
| 35 | SO_180;SO_181;;3;{SO_183,SO_181,SO_180} |
| 36 | SO_180;SO_181;;3;{SO_183,SO_181,SO_180} |
| 37 | SO_181;SO_183;;3;{SO_187,SO_183,SO_181} |
| 38 | SO_180;SO_183;;3;{SO_187,SO_183,SO_180} |
| 39 | .... |
| 40 | Donc j'enlève ensuite toutes les lignes contenant un élement de SO_180;SO_181;;5;{SO_188,SO_187,SO_183,SO_181,SO_180} |
| 41 | Puis je continue à l'étape 4 ... |
| 42 | |
| 43 | */ |
| 44 | |
| 45 | WITH grouped_array as( |
| 46 | WITH RECURSIVE graph as (SELECT sp1.id AS id1, sp2.id AS id2 FROM |
| 47 | sudoang.spain_obstruction_in_spain AS sp1 JOIN |
| 48 | sudoang.spain_obstruction_in_spain AS sp2 ON |
| 49 | ST_dwithin(sp1.geom, sp2.geom,10) |
| 50 | where sp1.id != sp2.id |
| 51 | and substring(sp1.id from 4) < substring(sp2.id from 4) |
| 52 | order by substring(sp1.id from 4)::numeric, |
| 53 | substring(sp2.id from 4)::numeric), |
| 54 | |
| 55 | search_graph(id1, id2, depth, path, cycle) AS ( |
| 56 | SELECT g.id1, g.id2, 1, |
| 57 | ARRAY[g.id1::text], |
| 58 | false |
| 59 | from graph g |
| 60 | UNION ALL |
| 61 | SELECT g.id1, g.id2, sg.depth + 1, |
| 62 | path || ARRAY[g.id1::text], |
| 63 | sg.id2 in (select g.id1 from graph) |
| 64 | FROM graph g, search_graph sg |
| 65 | WHERE g.id2 = sg.id1 |
| 66 | AND NOT cycle |
| 67 | ) |
| 68 | SELECT id1, id2, path, depth -- (cycle) j'ai plus besoin de cycle qui servait dans la partie récursive |
| 69 | FROM search_graph order by depth desc |
| 70 | ),--grouped_array, |
| 71 | chain5 as (select * from grouped_array where depth =5), |
| 72 | chain4 as (select * from grouped_array where depth =4), |
| 73 | chain3 as (select * from grouped_array where depth =3), |
| 74 | chain2 as (select * from grouped_array where depth =2), |
| 75 | |
| 76 | chain5_et_ses_petits as ( |
| 77 | select grouped_array.* from chain5 JOIN grouped_array on chain5.path && grouped_array.path), |
| 78 | |
| 79 | chain4_et_ses_petits as ( |
| 80 | select grouped_array.* from chain4 JOIN grouped_array on chain4.path && grouped_array.path |
| 81 | where chain4.path not in (select path from chain5_et_ses_petits)), |
| 82 | |
| 83 | chain3_et_ses_petits as ( |
| 84 | select grouped_array.* from chain3 JOIN grouped_array on chain3.path && grouped_array.path |
| 85 | where chain3.path not in (select path from chain4_et_ses_petits) |
| 86 | and chain3.path not in (select path from chain5_et_ses_petits)), |
| 87 | |
| 88 | chain2_et_ses_petits as ( |
| 89 | select grouped_array.* from chain2 JOIN grouped_array on chain2.path && grouped_array.path |
| 90 | where chain2.path not in (select path from chain3_et_ses_petits) |
| 91 | and chain2.path not in (select path from chain4_et_ses_petits) |
| 92 | and chain2.path not in (select path from chain5_et_ses_petits)), |
| 93 | |
| 94 | chain1 as ( |
| 95 | select * from grouped_array where depth=1 |
| 96 | and grouped_array.path not in (select path from chain2_et_ses_petits) |
| 97 | and grouped_array.path not in (select path from chain3_et_ses_petits) |
| 98 | and grouped_array.path not in (select path from chain4_et_ses_petits) |
| 99 | and grouped_array.path not in (select path from chain5_et_ses_petits)), |
| 100 | |
| 101 | bigunion as ( |
| 102 | select * from chain5_et_ses_petits where depth=5 |
| 103 | UNION |
| 104 | select * from chain4_et_ses_petits where depth=4 |
| 105 | UNION |
| 106 | select * from chain3_et_ses_petits where depth=3 |
| 107 | UNION |
| 108 | select * from chain2_et_ses_petits where depth=2 |
| 109 | UNION |
| 110 | select * from chain1) |
| 111 | |
| 112 | select * from bigunion order by depth desc, id1 |
| 113 | |
| 114 | /* |
| 115 | id1;id2;path;depth |
| 116 | SO_180;SO_181;{SO_188,SO_187,SO_183,SO_181,SO_180};5 |
| 117 | SO_2158;SO_2161;{SO_2164,SO_2162,SO_2161,SO_2158};4 |
| 118 | SO_14;SO_15;{SO_16,SO_15,SO_14};3 |
| 119 | SO_2195;SO_2196;{SO_2197,SO_2196,SO_2195};3 |
| 120 | SO_2697;SO_2698;{SO_2700,SO_2698,SO_2697};3 |
| 121 | SO_3049;SO_3050;{SO_3051,SO_3050,SO_3049};3 |
| 122 | SO_1472;SO_1945;{SO_1945,SO_1472};2 |
| 123 | SO_2641;SO_2642;{SO_2642,SO_2641};2 |
| 124 | SO_2682;SO_2683;{SO_2683,SO_2682};2 |
| 125 | SO_3084;SO_3086;{SO_3086,SO_3084};2 |
| 126 | SO_1046;SO_1252;{SO_1046};1 |
| 127 | SO_1047;SO_120;{SO_1047};1 |
| 128 | SO_1167;SO_3021;{SO_1167};1 |
| 129 | SO_118;SO_119;{SO_118};1 |
| 130 | SO_1217;SO_1398;{SO_1217};1 |
| 131 | SO_1234;SO_1235;{SO_1234};1 |
| 132 | SO_1243;SO_3102;{SO_1243};1 |
| 133 | SO_1282;SO_1283;{SO_1282};1 |
| 134 | SO_1299;SO_1300;{SO_1299};1 |
| 135 | SO_1302;SO_1303;{SO_1302};1 |
| 136 | SO_1309;SO_2232;{SO_1309};1 |
| 137 | SO_1312;SO_3276;{SO_1312};1 |
| 138 | SO_1504;SO_3308;{SO_1504};1 |
| 139 | SO_1518;SO_1519;{SO_1518};1 |
| 140 | SO_1567;SO_1568;{SO_1567};1 |
| 141 | SO_1635;SO_1637;{SO_1635};1 |
| 142 | SO_1852;SO_3344;{SO_1852};1 |
| 143 | SO_1868;SO_1869;{SO_1868};1 |
| 144 | SO_1902;SO_1903;{SO_1902};1 |
| 145 | SO_198;SO_491;{SO_198};1 |
| 146 | SO_2059;SO_2060;{SO_2059};1 |
| 147 | SO_2064;SO_3377;{SO_2064};1 |
| 148 | SO_2075;SO_2076;{SO_2075};1 |
| 149 | SO_2129;SO_2134;{SO_2129};1 |
| 150 | SO_2141;SO_3384;{SO_2141};1 |
| 151 | SO_2186;SO_2187;{SO_2186};1 |
| 152 | SO_2200;SO_2202;{SO_2200};1 |
| 153 | SO_229;SO_230;{SO_229};1 |
| 154 | SO_2299;SO_3412;{SO_2299};1 |
| 155 | SO_2303;SO_3413;{SO_2303};1 |
| 156 | SO_2320;SO_2321;{SO_2320};1 |
| 157 | SO_2323;SO_2324;{SO_2323};1 |
| 158 | SO_2340;SO_2341;{SO_2340};1 |
| 159 | SO_2366;SO_2367;{SO_2366};1 |
| 160 | SO_2393;SO_2395;{SO_2393};1 |
| 161 | SO_2396;SO_2397;{SO_2396};1 |
| 162 | SO_2450;SO_2451;{SO_2450};1 |
| 163 | SO_2507;SO_2594;{SO_2507};1 |
| 164 | SO_2567;SO_2569;{SO_2567};1 |
| 165 | SO_2585;SO_2586;{SO_2585};1 |
| 166 | SO_2770;SO_2771;{SO_2770};1 |
| 167 | SO_2812;SO_2822;{SO_2812};1 |
| 168 | SO_2842;SO_2843;{SO_2842};1 |
| 169 | SO_2847;SO_2848;{SO_2847};1 |
| 170 | SO_288;SO_874;{SO_288};1 |
| 171 | SO_2915;SO_2923;{SO_2915};1 |
| 172 | SO_2916;SO_2924;{SO_2916};1 |
| 173 | SO_292;SO_79;{SO_292};1 |
| 174 | SO_2979;SO_2980;{SO_2979};1 |
| 175 | SO_2981;SO_2983;{SO_2981};1 |
| 176 | SO_3026;SO_3027;{SO_3026};1 |
| 177 | SO_3081;SO_962;{SO_3081};1 |
| 178 | SO_313;SO_315;{SO_313};1 |
| 179 | SO_3150;SO_3153;{SO_3150};1 |
| 180 | SO_3170;SO_3171;{SO_3170};1 |
| 181 | SO_3185;SO_3614;{SO_3185};1 |
| 182 | SO_3329;SO_3330;{SO_3329};1 |
| 183 | SO_3386;SO_3387;{SO_3386};1 |
| 184 | SO_339;SO_340;{SO_339};1 |
| 185 | SO_3460;SO_3461;{SO_3460};1 |
| 186 | SO_3532;SO_3533;{SO_3532};1 |
| 187 | SO_3619;SO_3620;{SO_3619};1 |
| 188 | SO_374;SO_382;{SO_374};1 |
| 189 | SO_42;SO_44;{SO_42};1 |
| 190 | SO_456;SO_457;{SO_456};1 |
| 191 | SO_969;SO_971;{SO_969};1 |
| 192 | */ |
| 193 | }}} |