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 :

écrire une requête


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    mars 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mars 2007
    Messages : 31
    Points : 91
    Points
    91
    Par défaut écrire une requête
    Bonjour,

    Je ne fais pas beaucoup de sql et je dois écrire une requête un peu complexe (pour moi en tout cas )

    Je vais prendre un exemple :

    Une table "personne" avec un champ id et un champ nom.

    Une table "hotel" avec un champ id, un champ nom.

    Une table "personne_a_dormi" avec un id, une clef étrangère idPersonne et une clef étrangère idHotel et un champ a_dormi.

    Ce que je voudrais, comme résultat de requête, c'est quelque chose comme ça :
    | personne | |hotel1| |hotel2| |hotel3| |hotel4| .....
    personne1 oui non oui .....
    personne2 non ....
    ...

    Je ne sais pas si je suis clair ?

    En gros, je voudrais, pour toutes les personnes, voir tous les hotels.

    Zhebulonn

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Consultant Teradata
    Inscrit en
    septembre 2008
    Messages
    8 277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Teradata
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2008
    Messages : 8 277
    Points : 17 272
    Points
    17 272
    Par défaut
    Si possible, faites la mise en page dans votre application cliente, car le SQL est un langage déclaratif où le nombre de colonnes doit être connu avant d'écrire la requête.

    Sinon il s'agit simplement de deux jointures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select per.nom, hot.nom
      from personne per
           inner join personne_a_dormi pad
             on pad.idPersonne = per.id
           inner join hotel hot
             on hot.id = pad.idHotel

  3. #3
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : avril 2011
    Messages : 1 919
    Points : 3 296
    Points
    3 296
    Billets dans le blog
    1
    Par défaut
    Il a raison, on ne peut faire un select sur un nombre indéterminé de colonnes, la seule solution est une procédure stockée. En mysql ça donnerait ça:
    Code sql : 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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    -- uniquement pour le test
    drop database if exists hotels;
    create database hotels default character set utf8 collate utf8_general_ci;
    -- on sélectionne la bd quoi qu'il arrive pour bien travailler avec elle par défaut
    use hotels; -- à toi d'adapter
     
    -- on définit les tables et on les remplit uniquement pour le test
    create table hotel(
    	id		int(4) not null auto_increment,
    	nom	varchar(255) not null,
    	constraint pk_hotel primary key(id)
    )engine=myisam auto_increment=1;
    create table personne(
    	id		int(4) not null auto_increment,
    	nom	varchar(255) not null,
    	constraint pk_personne primary key(id)
    )engine=myisam auto_increment=1;
    -- la table de liaison, je ne mets pas de contrainte dessus car je la crée avec le moteur myisam qui ne s'en occupe pas
    create table personne_a_dormi(
    	id				int(4) not null auto_increment,
    	idPersonne 	int(4) not null,
    	idHotel		int(4) not null,
    	constraint pk_personne_a_dormi primary key(id)
    )engine=myisam auto_increment=1;
     
    insert into hotel(nom)values("hotel1"),("hotel2"),("hotel3");
    insert into personne(nom)values("personne1"),("personne2"),("personne3"),("personne4");
    insert into personne_a_dormi(idPersonne,idHotel)values(1,1),(1,2),(2,2),(3,1),(3,3),(4,1),(4,2),(4,3);
     
    -- on définit la procédure stockée
    drop procedure if exists recapitulatif;
    delimiter |
    create procedure recapitulatif()
    begin
    	declare ligne text default "personne";
    	declare tmp varchar(255);
    	declare done,test bool;
    	declare cpers,chotel int(4);
    	declare colonnes cursor for select nom from hotel;
    	declare lignes cursor for select id,nom from personne;
    	declare lithotel cursor for select id from hotel;
    	declare CONTINUE HANDLER for SQLSTATE '02000' set done = 1;
    	-- on crée l'entête
    	open colonnes;
    	set done=false;
    	repeat
    		fetch colonnes into tmp;
    		if not done then
    			set ligne=concat(ligne,",",tmp);
    		end if;
    	until done end repeat;
    	close colonnes;
    	select ligne as entete;
    	set done=false;
    	open lignes;
    	repeat
    		fetch lignes into cpers,tmp;
    		if not done then
    			set test=done;
    			set ligne=tmp;
    			open lithotel;
    			repeat
    				fetch lithotel into chotel;
    				if not done then
    					select if(count(id)>0,"Oui","Non") into tmp from personne_a_dormi where idPersonne=cpers and idHotel=chotel;
    					set ligne=concat(ligne,",",tmp);
    				end if;
    			until done end repeat;
    			close lithotel;
    			select ligne;
    			set done=test;
    		end if;
    	until done end repeat;
    	close lignes;
    end|
    delimiter ;
    -- fin de la procédure stockée
     
    -- on teste en appelant la procédure
    call recapitulatif();

    Le résultat est ce que tu voulais, du moins au mieux de ce que l'on peut pondre avec les contraintes de sql
    Un résultat d'une ligne qui est l'entête, suivie d'un résultat d'une ligne par personne, les valeurs sont séparées par une virgule.

    Tu dois donc pouvoir manipuler une requête à résultats multiples (mysqli ou pdo pour mysql principalement avec un petit réglage)...

    A toi d'adapter ceci à ton sgbd si c'est pas mysql car chacun fait sa vie vis à vis de l'écriture sql et tu trouveras un autre pour t'aider à le faire

    Si tu veux que l'intégrité référentielle soit respectée sur la table de liaison il faut utiliser le moteur innodb à la place de myisam sur cette table.

    voilà
    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  4. #4
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    juin 2003
    Messages
    1 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : juin 2003
    Messages : 1 121
    Points : 1 397
    Points
    1 397
    Par défaut
    bonjour

    PIVOT fait ce genre de choses (sous MS SQL).

    Penses a jeter un coup d'oeuil sur le forum avec ce mot

    a+
    olivier
    Merci d'ajouter un sur les tags qui vous ont aidé

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    mars 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mars 2007
    Messages : 31
    Points : 91
    Points
    91
    Par défaut
    Merci beaucoup pour vos réponses.

    Je n'ai pas encore eu le temps d'essayer.

    Je vous tiens au courant.

  6. #6
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : avril 2011
    Messages : 1 919
    Points : 3 296
    Points
    3 296
    Billets dans le blog
    1
    Par défaut
    à savoir que avec peu de modifications tu peux les différents résultats en un seul au format xml en rajoutant quelques concat, après tout dépend de tes besoins
    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  7. #7
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    novembre 2004
    Messages
    1 792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    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 792
    Points : 3 127
    Points
    3 127
    Par défaut
    Si possible, faites la mise en page dans votre application cliente, car le SQL est un langage déclaratif où le nombre de colonnes doit être connu avant d'écrire la requête.
    J'abonde...
    Cela vous évitera le code de ericd69 qui est tout sauf une solution...
    avec les contraintes de sql
    Permettez moi de rigoler... sql n'a pour le coup que les contraintes qu'on veut bien lui donner, en l’occurrence souvent une modélisation perfectible...

    La 'solution' côté SQL serait un pivot mais je crois que (lui aussi) n'est pas implémenté dans mySQL.
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Citation Envoyé par iberserk Voir le message
    La 'solution' côté SQL serait un pivot mais je crois que (lui aussi) n'est pas implémenté dans mySQL.
    Bonjour,

    c'est implémenté :
    http://dev.mysql.com/doc/refman/5.0/...n_group-concat

  9. #9
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : avril 2011
    Messages : 1 919
    Points : 3 296
    Points
    3 296
    Billets dans le blog
    1
    Par défaut
    la réduction des échanges sgbd/application peut être aussi un critère...

    y a jamais une seule solution pour faire les chose et une seule optimisation... ça dépend de tes besoins

    toutes les solutions proposées ici se valent mais certaines peuvent être plus adaptées selon tes contraintes (principalement les caractéristiques de fonctionnement de ton mysql)...

    ps: j'adore l'intégrisme de certains!
    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  10. #10
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    novembre 2004
    Messages
    1 792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    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 792
    Points : 3 127
    Points
    3 127
    Par défaut
    ps: j'adore l'intégrisme de certains!
    Pas de problème il est assumé à 100%, etpour cause:

    Je passe mon temps à reprendre ce genre de code une fois les applications tombées en prod...

    Et je peut vous dire que je suis 'doux' certains machent moins leurs mots...
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  11. #11
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : avril 2011
    Messages : 1 919
    Points : 3 296
    Points
    3 296
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par iberserk Voir le message
    Pas de problème il est assumé à 100%
    y a pas de soucis moi aussi ça m'arrive mais il faut se dire qu'il n'y a pas qu'un chemin pour aller au but

    et parfois, quand tu vois comment sont codés des trucs genre phpbb, dotclear ou autres... ça fait peur

    après faut pas être trop formaliste non plus... je l'ai pas pris mal...

    Perso, utiliser une subtilité de programmation pour limiter l'usage de bp et donner un résultat qui est récupéré avec un simple split pour etre transformer en tableau en php je trouve ça plus pas si mal... le langage est un outil pas forcément une fin en soit et la répartition sgbd/appli pour le traitement peut toujours se discuter... Le traitement que tu proposes est tout aussi valable.

    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  12. #12
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    mai 2002
    Messages
    21 143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : mai 2002
    Messages : 21 143
    Points : 50 169
    Points
    50 169
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par iberserk Voir le message
    Pas de problème il est assumé à 100%, et pour cause:

    Je passe mon temps à reprendre ce genre de code une fois les applications tombées en prod...

    Et je peut vous dire que je suis 'doux' certains mâchent moins leurs mots...
    Tu m'as appelé ??? ;-)

    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/ * * * * *

  13. #13
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    novembre 2004
    Messages
    1 792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    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 792
    Points : 3 127
    Points
    3 127
    Par défaut
    Tu m'as appelé ??? ;-)

    A +
    Moi? pas du tout
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

Discussions similaires

  1. Réponses: 1
    Dernier message: 25/08/2011, 00h17
  2. Besoin d'aide pour écrire une requête SQL
    Par tompintures dans le forum Requêtes
    Réponses: 2
    Dernier message: 31/01/2011, 10h47
  3. Besoin d'aide pour écrire une requête
    Par Jean-Marc68 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/10/2009, 19h54
  4. Réponses: 1
    Dernier message: 26/08/2008, 14h26
  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