Recette
#17 |
|
Février 2011 |
Le problème ici, on utilisera également la
table railways.
Le problème que vous devez résoudre est le suivant:
|
Railway |
PopulatedPlace |
A class [< 1Km] |
B class [< 2.5Km] |
C class [< 5Km] |
D class [< 10Km] |
E class [< 20Km] |
Ferrovia Adriatica |
Zapponeta |
NULL |
NULL |
NULL |
NULL |
1 |
Ferrovia Adriatica |
Villamagna |
NULL |
NULL |
NULL |
NULL |
1 |
Ferrovia Adriatica |
Villalfonsina |
NULL |
NULL |
NULL |
1 |
0 |
Ferrovia Adriatica |
Vasto |
1 |
0 |
0 |
0 |
0 |
... |
... |
... |
... |
... |
... |
... |
SELECT rw.name AS
Railway, |
Oui, cette requête est complexe et
intimidante.
Cependant, en y regardant de plus près, elle reste
abordable.
Vous connaissez déjà l'astuce: disséquer la requête
pièce par pièce.
Examinons le squelette de la requète:
SELECT rw.name AS
Railway, ... |
on réalise simplement une JOINture des tables railways AS rw et populated_places AS pp_e
puis on réalise un LEFT JOIN de la table populated_places AS pp_d (2ème instance de la table): comme vous le savez LEFT JOIN insère une ligne dans les résultats même si le terme de droite est évalué NULL.
enfin, on répète le LEFT JOIN avec pp_c, pp_b et pp_a.
On va commencer par évaluer la plus grande distance et on continue selon les distances décroissantes.
... |
Chaque JOIN (ou LEFT JOIN) évalue simplement la distance entre Railway et Populated Place, et vérifie qu'elle appartient bien à la classe correspondante
la fonction Transform() est indispensable car les SRID ne sont pas identiques pour les deux jeux de donnée.
... AND pp_e.id IN
( |
l'utilisation de l'Index Spatial est également nécessaire afin de filtrer rapidement les géométries des Populated Places.
ici encore, Transform()est indispensable pour reprojeter la géométrie de railway.
note: transformer les coordonnées d'un POINT
peut être considéré comme une opération rapide;
mais
transformer (des centaines et des centaines de fois …) des
LINESTRING ou
POLYGON est
beaucoup plus lent.
On utilisera ainsi la fonction ST_Envelope()
afin de simplifier au maximum la géométrie avant la transformation
des coordonnées.
Bien, la structure de la requête est maintenant claire:
|
SELECT rw.name AS
Railway, |
Juste un dernier point a expliquer:
considérons une distance e.g. 3.8 Km: elle est incluse dans la classe C-class. mais cette condition satisfait le LEFT JOIN pour les classes D et E également .
il est donc nécessaire d'effectuer une vérification supplémentaire.
fort heureusement SQL est un langage très intelligent. Toute colonne incluse dans les résultats peut représenter n'importe quelle expression voulue.
En SQL une expression logique est évaluée comme:
0 [FAUX]
1 [TVRAI]
ou NULL, si un des opérateurs évalués est NULL.
et c'est tout.
A vous de jouer, et de pousser plus loin cette analyse. |
|
Author: Alessandro Furieri a.furieri@lqt.it |
This work is licensed under the Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) license. |
|
|
|
Permission is granted to copy, distribute and/or modify this
document under the terms of the |