Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/05/2011, 19h11   #1
Membre du Club
 
Inscription : mars 2006
Messages : 333
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 333
Points : 69
Points : 69
Par défaut Problème de requête

Salut,

Desolé pour la question de noob mais ca fait 2 heures que je me prend la tete pour essayer formuler une requete ...
(J utilise Sqlite)

Voila mon probleme :

Pour simplifier, disons que j ai deux tables Noeuds et Liens avec les attributs:

Noeuds (id, type, lieu)
Liens (id, type, noeud_From, noeud_to)

Supposons aussi que pour 1 lieu du tableau Noeuds, j ai 3 types differents de noeuds: Hopital, Eglise, Ecole.

Mon probleme est qu ' a l heure actuelle mes liens du type qui m interesse ont tous comme noeud de depart Hopital alors que je voudrais Eglise.

Donc ce que je voudrais faire, c'est changer l attribut "noeud_From" du tableau liens, depuis le noeuds.id de l hopital pour l'Eglise du meme lieu.

J espere que je suis clair ...


En decomposant le probleme je suppose que ce qu il me faut est :

- Utiliser un select sur "Liens", pour selectioner uniquement le type de liens qui m interesse. (disons type=8)

- Identifier a quel lieu appartient le noeud de depart.

- Identifier le noeud Eglise pour le meme lieu

- Utiliser un Update pour mettre a jour l'attribut noeud_from.

Mais voila, je n arrive pas dutout a "emboiter les morceaux ..."

Si quelqu un pouvait m aider svp ...

Merci

Slumpy
Slumpy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/05/2011, 19h42   #2
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
bonjour,

Non vous n'etes pas clair.

http://sqlpro.developpez.com/cours/arborescence/

Regardez ce lien déjà.

Ensuite si vous n'arrivez à vous dépatouiller tout seul, mettez un exemple de donnée avec ce que vous avez actuellement et votre but.

edit : enfin je commence peut-etre à comprendre. Pourquoi n'updatez-vous tout simplement pas le type ? ca sera moins compliquer que de vous amusez à changer toute votre arborescence
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/05/2011, 20h27   #3
Membre du Club
 
Inscription : mars 2006
Messages : 333
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 333
Points : 69
Points : 69
Salut punkoff et merci d avoir pris la peine de répondre.

J ai regardé le liens que vous m avez indiqué. Je n ai pas lu en détail la partie sur les procédures stockées, mais mis a part ca tout le reste ne me pose pas de problème.

Je ne sais pas trop comment l expliquer, mais je ne peux pas "updater" le type de nœud.

Imaginons le tableau Nœud :

id    type    lieu
1    Hopital   Toulouse
2    Eglise    Toulouse
3    Ecole     Toulouse
4    Hopital   Dax
5    Eglise    Dax
6    Ecole     Dax
7    Hopital   Bordeaux
8    Eglise    Bordeaux
9    Ecole     Bordeaux
le tableau Liens :
id       type            noeud_from       noeud_to
1        autoroute            1               7
2        chemin               2               3
3        saniter              7               8
4        saniter              8               9
5        autoroute            4               3
6        chemin               4               5
Comme vous pouvez le voir, dans nœuds, chaque ville a trois nœuds (Église, École, Hôpital). Aussi, chaque autoroute démarre d un nœud qui est un hôpital, pour joindre n'importe quel type de nœud.

Ce que j ai besoin de faire est de changer le nœud de départ de mes liens. Par exemple, je voudrais que toutes mes autoroutes partent de l'Église de la ville et non pas de l'hôpital.

Dans ce cas la mon tableau résultat après l'Update serait :

id    type      noeud_from    noeud_to
1    autoroute      2            7
2    chemin         2            3
3    saniter        7            8
4    saniter        8            9
5    autoroute      5            3
6    chemin         4            5
(voir élément 1 et 5).

J espère être plus clair ?

Merci encore

Slumpy.
Slumpy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/05/2011, 20h42   #4
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
n'auriez vous pas un problème de modélisation ?

vous vous servez des id (primary key) pour ordonner vos "déplacements" ce qui n'est pas logique.

de plus vous avez un problème de redondance de données (si fsmrel passe dans le coin il pourra mieux le décrire que moi).


bref pour moi il vous manque une ou deux tables, mais sans connaitre l'aspect fonctionnel ça me semble tendu.

Est-ce que votre modèle de données est figé ?
- si oui on essaiera de trouver un compromis
- si non je vous invite de passer par la case modélisation (de ce forum) pour exposer clairement votre besoin et repenser à tout ça à tête reposée

edit :
Une idée de départ serai de scinder votre table noeuds.

N'y mettre que les villes, ensuite créer 2 autres table :
- une qui recense les différents type de lieux communs à toutes les villes.
- et une table d'association qui permet de relier une ville à un lieu avec en plus une colonne de classement.

Maintenant cela risque de se compliquer si vous voulez faire des chemins différent entre les lieux de chaque ville et les liens, il faudra envisager un modèle plus complexe.

Donc oui allez faire un tour sur le forum de modélisation
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/05/2011, 21h01   #5
Membre du Club
 
Inscription : mars 2006
Messages : 333
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 333
Points : 69
Points : 69
Rebonjour,

Et encore merci pour votre temps.

En fait, cette base Sqlite est utilisée par un logiciel extérieur pour faire un certain nombre de calculs. Je ne possède pas le code de cet outil extérieur et ne peux donc pas changer la structure de la base de données. Sous peine de plus pouvoir utiliser cet outil.

Malgré mon niveau plutôt débutant en SQL, j'ai remarqué que la base de données était plutôt mal structurée, c'est vous dire .... Mais bon, me faut faire avec.

Effectivement, je me sers des id. C'est ma seule manière d'identifier qui est qui ... dans cette histoire.

Slumpy
Slumpy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/05/2011, 21h17   #6
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
oki,

faites un test avant sur une base de test ... je n'ai pas testé ces requêtes et je pars du principe que votre base suit le même modèle pour toutes les données.

Mais l'idée générale est là :

Code :
1
2
3
4
 
UPDATE noeuds SET type = 'Hopital' WHERE type = 'Eglise' AND EXISTS (SELECT 1 FROM lien WHERE noeud_from >= noeuds.id AND noeud_to <= noeuds.id AND lien .id = ....);
 
UPDATE noeuds SET type = 'Eglise' WHERE id IN (SELECT min(id) FROM noeuds WHERE type = 'Hopital' GROUP BY lieu) AND EXISTS (SELECT 1 FROM lien WHERE noeud_from >= noeuds.id AND noeud_to <= noeuds.id AND lien .id = ....);
Dans un premier temps on change le type et ensuite on rechange que le min ou max d'une ville.

Attention si jamais vous avez des lieux qui n'ont pas ces 2 occurrences distinctes il faudra changer les requêtes !
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/05/2011, 21h39   #7
Membre du Club
 
Inscription : mars 2006
Messages : 333
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 333
Points : 69
Points : 69
Merci pour la requête, je vais essayer de la comprendre dans l'esprit et le détail, mais je ne suis pas sur que l'on essaye de faire la même chose

Je suis surpris que vous vouliez mettre à jour les noeuds. C'est le noeud_from qu il faut changer plutôt non ?

Moi je voyais le truc plutôt comme:
(Attention, ca va piquer les yeux ....)

Code :
1
2
3
4
5
 
1 - SELECT noeud_from FROM Liens WHERE type="Autoroute"
2 - SELECT Lieu FROM Noeuds WHERE id = reponse precedente
3 - SELECT id FROM Noeuds WHERE (type="Ecole" AND Lieu= reponse precedente)
4 - UPDATE FROM Liens SET noeud_from=reponse precedente
.

Merci

Slumpy
Slumpy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/05/2011, 08h08   #8
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
Citation:
Envoyé par Slumpy Voir le message
Merci pour la requête, je vais essayer de la comprendre dans l'esprit et le détail, mais je ne suis pas sur que l'on essaye de faire la même chose
Non effectivement on tente de faire quelquechose différente car j'étais parti du principe que votre table lien était un arbre mais ca n'est pas du tout le cas !

Du coup voilà une requete qui devrait répondre mieux à votre besoin.
Elle est peut être optimisable mais je n'ai pas le temps ce matin

Code :
1
2
3
4
5
6
 
UPDATE liens a SET noeud_from = (SELECT  b.id FROM noeuds b WHERE b.type = 'Eglise' AND 
    EXISTS (SELECT 1 FROM noeuds c WHERE  c.id = a.noeud_from AND c.type = 'Hopital' AND c.ville = b.ville) )
WHERE EXISTS (SELECT 1 FROM noeuds b WHERE b.type = 'Eglise'  AND 
    EXISTS (SELECT 1 FROM noeuds c WHERE c.id = a.noeud_from AND c.type = 'Hopital' AND c.ville = b.ville)) 
AND a.type = 'autoroute';
je l'ai testé avec votre exemple de jeu de donnée et le résultat est le même.

Code :
1
2
3
4
5
6
7
8
9
 
Liens
id     type          nF     Nt
1	autoroute	2	7
2	chemin	2	3
3	saniter	7	8
4	saniter	8	9
5	autoroute	5	3
6	chemin	4	5
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 31/05/2011, 14h14   #9
Membre du Club
 
Inscription : mars 2006
Messages : 333
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 333
Points : 69
Points : 69
Salut punkoff,

Citation:

Code :Sélectionner tout - Visualiser dans une fenêtre à part123456
UPDATE liens a SET noeud_from = (SELECT b.id FROM noeuds b WHERE b.type = 'Eglise' AND
EXISTS (SELECT 1 FROM noeuds c WHERE c.id = a.noeud_from AND c.type = 'Hopital' AND c.ville = b.ville) )
WHERE EXISTS (SELECT 1 FROM noeuds b WHERE b.type = 'Eglise' AND
EXISTS (SELECT 1 FROM noeuds c WHERE c.id = a.noeud_from AND c.type = 'Hopital' AND c.ville = b.ville))
AND a.type = 'autoroute';
Merci pour ca. Tu m etonnes que j arrivais pas a emboiter les morceaux ! C'est largement au dessus de mes competences actuelles. Merci.

Par contre, j ai un probleme pour l appliquer. Apparemment SQLite, n aime pas le fait de passer une table en parametre pour un Update. Je m explique :

Code :
SELECT * FROM networks AS a WHERE a.id=1
Me retourne une ligne correspondant a id=1 pour le tableau networks.

Code :
UPDATE networks SET name="tata" WHERE id=1
Me mets a jour le champ name du tableau networks pour lequel id=1.

Code :
UPDATE networks AS a SET name="tata" WHERE a.id=1
Me retourne l'erreur: near "AS": syntax error

Du coup, je ne peux pas appliquer la requete ...

Slumpy

EDIT :
Par contre, la requete suivante a l air de fonctionner. Y a t il un danger de ne pas savoir de quelle table/resultat on parle pour ce que tu appelais "a" ?

Code :
1
2
3
4
5
UPDATE liens SET noeud_from = (SELECT  b.id FROM noeuds b WHERE b.type = 'Eglise' AND 
    EXISTS (SELECT 1 FROM noeuds c WHERE  c.id = liens.noeud_from AND c.type = 'Hopital' AND c.ville = b.ville) )
WHERE EXISTS (SELECT 1 FROM noeuds b WHERE b.type = 'Eglise'  AND 
    EXISTS (SELECT 1 FROM noeuds c WHERE c.id = liens.noeud_from AND c.type = 'Hopital' AND c.ville = b.ville)) 
AND liens.type = 'autoroute';
Slumpy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/05/2011, 14h55   #10
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
Ne connaissant pas SQLite je ne peux pas répondre à cette question, désolé.

Mais à vue de nez ça me semble correct. Le tout est que tu n'aies pas plusieurs tables qui partagent le même nom au niveau des exists.
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/06/2011, 06h44   #11
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
UPDATE networks AS a SET name="tata" WHERE a.id=1
En effet cette syntaxe nest pas correcte pour un UPDATE/INSERT/DELETE
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/06/2011, 09h29   #12
Membre éprouvé
 
Inscription : janvier 2009
Messages : 301
Détails du profil
Informations personnelles :
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2009
Messages : 301
Points : 454
Points : 454
Bonjour,

Slumpy
Citation:
Code :
Sélectionner tout - Visualiser dans une fenêtre à part

UPDATE networks AS a SET name="tata" WHERE a.id=1

Me retourne l'erreur: near "AS": syntax error
Effectivement, Sqlite n'accepte pas un alias pour une table dans cette situation. Il faut savoir que Sqlite n'est pas un serveur de BD traditionnelles d'où des limitations dans sa syntaxe.

A+
seabs est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/06/2011, 18h41   #13
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
Effectivement, Sqlite n'accepte pas un alias pour une table dans cette situation. Il faut savoir que Sqlite n'est pas un serveur de BD traditionnelles d'où des limitations dans sa syntaxe.
C'est le cas de SQL SERVER aussi, les gens de chez MICROSOFT seront content de vous écouter

SQL est une norme et cette syntaxe n'en fait pas partie...
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h29.


 
 
 
 
Partenaires

Hébergement Web