IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Requête complexe, à l'aide


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Inscrit en
    Janvier 2009
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Requête complexe, à l'aide
    Bonjour,

    Je dois faire une requête afin de trouver les chevauchements d'adresses dans des bouts de rues.

    Voici la requête de base sur toute la table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from voi_troncon_ln_v where n_voie is not null
    (Voir fichier attaché requeteBase.jpg)
    Nom : RequeteBase.JPG
Affichages : 70
Taille : 77,6 Ko

    En considérant les adresses par rue (distinct t_voie, l_voie, n_voie,d_voie ou group by t_voie, l_voie, n_voie,d_voie ), on doit déterminer si dans l'ensemble des enregistrements, il y a des adresses (champs D_GCH, F_GCH, D_DRT, F_DRT) qui sont incluses dans d'autres enregistrements.

    D_GCH=> Début gauche
    F_GCH=> Fin gauche
    D_DRT=> Début droit
    F_DRT=> Fin droit

    on n'a pas à distinguer la gauche de la droite mais on doit distinguer les pairs des impairs (mod(b.d_drt,2) = mod(a.d_drt,2) ou mod(b.d_gch,2) = mod(a.d_gch,2)).

    Par exemple, la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select * 
    from voi_troncon_ln_v 
    where id_trc in (520774,503975,508874, 503261, 503264, 503971, 503216)
    montre les enregistrements dans l'image suivante, sur une rue en particulier.
    Nom : Image1.JPG
Affichages : 65
Taille : 77,2 Ko

    Ce qu'il faut considérer dans la requête:
    -Le ID_TRC=503216 n'entre pas dans la comparaison car il n'y a pas d'adresse associé à ce bout de rue (les champs D_GCH, F_GCH, D_DRT, F_DRT sont tous à 0). On peut donc mettre dans la requête and not(d_gch=0 and d_drt=0). Si les deux sont à 0, impossible qi'il y ait chevauchement.
    -Le ID_TRC=503971 côté droit (411 à 411) n'entre pas en conflit (pas de chevauchement) entre le tronçon ID_TRC=508874 (368 à 508) car le premier est impair alors que le second est pair, de même que les autres de l'exemple. Mais le côté gauche (400 à 400) chevauche le 508874 (368 à 508).
    -Finalement, on voit que le tronçon ID_TRC=508874 entre en conflit avec les tronçons ID_TRC=520774, 503975, 503261 et 503264. L'adresse 380 entre sur les tronçons 520774, 503975 et 508874. C'est ce qu'il faut trouver pour l'ensemble de la table. De même, l'adresse 420 entre sur les tronçons 508874 ET 503261. Et finalement, l'adresse 460 entre sur les tronçons 503264 ET 508874.

    Comment peut-on constituer la requête qui va faire en sorte qu'on va trouver les chevauchements pour tous les bouts de rues de cette table?

    Jusqu'à maintenant, j'ai trouvé ça comme requête mais ça ne semble pas fonctionner:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    select a.*
    from voi_troncon_ln_v a
    where a.objectid > (select min(b.objectid)
    from voi_troncon_ln_v b
    where b.t_voie = a.t_voie
    and b.l_voie = a.l_voie
    and b.n_voie = a.n_voie
    and b.d_voie = a.d_voie
    and (( 
    ( b.d_drt>0
    and mod(b.d_drt,2) = mod(a.d_drt,2) 
    and (b.d_drt between a.d_drt 
    and nvl(a.f_drt,a.d_drt) 
    or b.f_drt between a.d_drt 
    and nvl(a.f_drt,a.d_drt)) 
    ))
    OR
    ( 
    ( b.d_gch>0
    and mod(b.d_gch,2) = mod(a.d_gch,2) 
    and (b.d_gch between a.d_gch 
    and nvl(a.f_gch,a.d_gch) 
    or b.f_gch between a.d_gch 
    and nvl(a.f_gch,a.d_gch)) 
    ))
    )
    )
    and not(a.d_gch=0 and a.d_drt=0)

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 772
    Points : 52 732
    Points
    52 732
    Billets dans le blog
    5
    Par défaut
    MERCI de respecter la charte de postage en :

    1) Donnez les ordres SQL de création de vos tables (DDL SQL) (CREATE TABLE) ainsi que les INSERT d'un jeu de données basique afin que tout un chacun puisse reproduire ce que vous voulez faire sur son SGBDR afin de mieux vous aider.
    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     CREATE TABLE MaTable
    (Col1 VARCHAR(128),
     Col2 INTEGER,
     Col3 DATE,
     Col4 CHAR(32),
     CONSTRAINT PK_MaTable PRIMARY KEY (COL1, COL2))
     
    INSERT INTO MaTable (COL1, COL2, COL3) 
    VALUES ('Un mot', 32, CURRENT_TIMESTAMP)
    INSERT INTO MaTable (COL1, COL2, COL3) 
    VALUES ('Deux maux', 0, NULL)

    Tous les SGBDR sont dotés d'un outil permettant d'obtenir au moins le DDL (CREATE...) de vos tables. Exemple avec MS SQL Server 2000 : Entreprise manager, clic droit sur la base, menue toutes les tâches/Générer un script SQL...

    2) Présentez le résultat que vous voulez voir apparaître sous la forme d'une table
    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    -- Le résultat attendu :
    NOM     VILLE       NOMBRE 
    ------  ----------  ------ 
    MARTIN  PARIS            2 
    DUPOND  STRASBOURG       3
    ...
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 281
    Points : 11 737
    Points
    11 737
    Par défaut
    Puisqu'on compare, non pas des tronçons, mais des côtés pairs ou impairs de tronçons, il nous faut constituer une liste de ces côtés de troncons qui précise quatre infos : une id de côté de voie (qui semble être ton ID_REG/ID_RED), le type de côté (REG ou RED), le n° de début et le n° de fin.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    select ID_TRC, ID_REG as id_cotevoie, 'G' as typecote, D_GCH as deb, F_GCH as fin
    from voi_troncon_ln_v
    where n_voie is not null
      and D_GCH != 0 
    union all
    select ID_TRC, ID_RED, 'D', D_DRT, F_DRT
    from voi_troncon_ln_v
    where n_voie is not null
      and D_DRT != 0
    Pour exploiter cette liste, il y a plusieurs solutions (table dérivée, vue, table temporaire, CTE). Sur les copies écrans, je crois reconnaître la version pour Oracle de Toad, je vais donc supposer qu'il s'agit d'un Oracle récent, et utiliser une CTE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    with demitroncons as
    (
    select ID_TRC, ID_REG as id_cotevoie, 'G' as typecote, D_GCH as deb, F_GCH as fin
    from voi_troncon_ln_v
    where n_voie is not null
      and D_GCH != 0 
    union all
    select ID_TRC, ID_RED, 'D', D_DRT, F_DRT
    from voi_troncon_ln_v
    where n_voie is not null
      and D_DRT != 0
    )
    select T1.ID_TRC, 'recouvre', T2.ID_TRC
    from demitroncons T1
      inner join demitroncons T2 
        on T1.id_cotevoie = T2.id_cotevoie and T1.typecote = T2.typecote
          and T1.deb <= T2.fin and T1.fin >= T2.deb 
    where T1.ID_TRC < T2.ID_TRC
    A noter que le dernier WHERE permet à la fois d'éliminer les doublons (donc "b recouvre a" pour chaque "a recouvre b") et les auto-recouvrements ("a recouvre a").
    Antoun
    Expert Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

  4. #4
    Candidat au Club
    Inscrit en
    Janvier 2009
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Wow, la requête... pour un novice comme moi

    Un très gros merci Antoun ta précisieuse aide. J'ai ajouté une autre condition afin de vérifier les pairs/impairs (... and mod(T1.deb,2)=mod(T2.deb,2)).

    Dominic Lavoie


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
      with demitroncons as
    (
    select ID_TRC, ID_REG as id_cotevoie, 'G' as typecote, D_GCH as deb, F_GCH as fin
    from voi_troncon_ln_v
    where n_voie is not null
      and D_GCH != 0 
    union all
    select ID_TRC, ID_RED, 'D', D_DRT, F_DRT
    from voi_troncon_ln_v
    where n_voie is not null
      and D_DRT != 0
    )
    select T1.ID_TRC, 'recouvre', T2.ID_TRC
    from demitroncons T1
      inner join demitroncons T2 
        on T1.id_cotevoie = T2.id_cotevoie and T1.typecote = T2.typecote
          and T1.deb <= T2.fin and T1.fin >= T2.deb 
    	  and mod(T1.deb,2)=mod(T2.deb,2)
    where T1.ID_TRC < T2.ID_TRC

  5. #5
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 281
    Points : 11 737
    Points
    11 737
    Par défaut
    Citation Envoyé par DOUM555 Voir le message
    Wow, la requête... pour un novice comme moi

    Un très gros merci Antoun ta précisieuse aide. J'ai ajouté une autre condition afin de vérifier les pairs/impairs (... and mod(T1.deb,2)=mod(T2.deb,2)).
    Normalement tu n'as pas besoin, parce que si c'est le même côté gauche ou droit, c'est forcément le même côté pair ou impair... mais je t'invite à tester si ça fait une différence ou pas dans le nombre de lignes.
    Antoun
    Expert Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

  6. #6
    Candidat au Club
    Inscrit en
    Janvier 2009
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    ouen, non ici, il peut y avoir autant des pairs à gauche ou à droite et vice versa. C'est pourquoi il faut que je vérifie la parité

    As-tu déjà eu à dealer avec des adresses sur des tronçons, et donc que t'es familié avec ça ou bien t'es juste très à l'aise avec le sql?

    En tout cas, un gros merci

  7. #7
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 281
    Points : 11 737
    Points
    11 737
    Par défaut
    Citation Envoyé par DOUM555 Voir le message
    ouen, non ici, il peut y avoir autant des pairs à gauche ou à droite et vice versa. C'est pourquoi il faut que je vérifie la parité
    Sur une la même voie, le côté gauche est toujours pair ou toujours impair. Donc si deux demi-tronçons de la même voie ont la même latéralité, ils ont forcément la même parité (même si on ne sait pas laquelle).
    Citation Envoyé par DOUM555 Voir le message
    As-tu déjà eu à dealer avec des adresses sur des tronçons, et donc que t'es familié avec ça ou bien t'es juste très à l'aise avec le sql?
    En fait, j'ai pas mal travaillé sur des recouvrements de périodes. Donc quand j'ai compris qu'il suffisait de ramener ton problème à une simple question de recouvrement (avec l'UNION), j'avais trouvé la solution.

    Sinon, ça va, je ne suis pas trop manche avec le SQL

    En tout cas ton problème était très intéressant !
    Antoun
    Expert Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. générer des donnees / aide pour requête complexe
    Par djinnwatcher dans le forum Débuter
    Réponses: 7
    Dernier message: 10/08/2009, 13h56
  2. Aide pour requête complexe
    Par marivi dans le forum Langage SQL
    Réponses: 2
    Dernier message: 26/09/2007, 17h27
  3. aide pour une requête complexe
    Par marsupio49 dans le forum Oracle
    Réponses: 13
    Dernier message: 11/06/2007, 16h37
  4. [MSSQL2005] Besoin d'aide pour une requête complexe
    Par Vonotar dans le forum Langage SQL
    Réponses: 4
    Dernier message: 17/01/2007, 16h47
  5. Aide pour écrire une requête complexe
    Par julienbdx dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 29/11/2005, 16h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo