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 :

Pb avec case when !


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Inscrit en
    Septembre 2002
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 14
    Points : 10
    Points
    10
    Par défaut Pb avec case when !
    Salut à tous!
    J'ai un pb en sql avec une requete qui ne me donne pas le resultat souhaité.
    Voici ma requette:

    select r.numcarte,r.nomprenoms,datepart(wk,datejour)as 'semaine',datepart(dw,datejour)as 'jour',
    CASE datepart(dw,datejour) WHEN 1 THEN r.he+'-'+r.hs END AS lundi,
    CASE datepart(dw,datejour) WHEN 2 THEN r.he+'-'+r.hs END AS Mardi,
    CASE datepart(dw,datejour) WHEN 3 THEN r.he+'-'+r.hs END AS Mercredi,
    CASE datepart(dw,datejour) WHEN 4 THEN r.he+'-'+r.hs END AS Jeudi,
    CASE datepart(dw,datejour) WHEN 5 THEN r.he+'-'+r.hs END AS Vendredi
    from resultatsfin r, employes e
    where r.numcarte=e.emp_numero_badge and datepart(wk,datejour)='1'
    group by r.numcarte,r.nomprenoms,datepart(wk,datejour),datepart(dw,datejour)


    et voici le resultat:

    • numcarte nomprenoms semaine jour lundi mardi mercredi ...
      num1 nom1 1 1 he-hs null null ...
      num1 nom1 1 2 null he-hs null ...
      num1 nom1 1 3 null null he-hs ...
      num2 nom2 1 1 he-hs null null ...
      num2 nom2 1 2 null he-hs null ...
      num2 nom2 1 3 null null he-hs ...

    Je vuex pourtant avoir ceci et je n'y arrive pas:

    • numcarte nomprenoms semaine lundi mardi mercredi ...
      num1 nom1 1 he-hs he-hs he-hs ...
      num2 nom2 1 he-hs he-he he-hs ...

    c'est-a-dire pour chaque nom avoir l'heure d'entrée (he)et de l'heure de sortie (hs)
    dans la période d'une semaine sur la même ligne.

    Voulez-vous m'aider SVP !
    merci.

  2. #2
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Essaye de retirer ) datepart(dw,datejour) du GROUP BY
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  3. #3
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Au passage, je voudrais juste poser une question (à laquelle Médiat va surement répondre ) sur la manière dont la jointure est faite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    from resultatsfin r, employes e 
    where r.numcarte=e.emp_numero_badge and datepart(wk,datejour)='1' ...
    Est-ce que ça ne serait pas plus performant de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    FROM resultatsfin r
    INNER JOIN employes e ON (r.numcarte = e.emp_numero_badge AND datepart(wk,datejour)='1')...
    Je dis ça en supposant que dans le cas de Brice Yao un produit cartésien est effectué en premier, puis la clause WHERE effectue un filtre sur les données du produit cartésien alors que dans la solution que je propose, la requête considère directement les données jointes des tables resultatsfin et employes.
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  4. #4
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Magnus :

    Il y a un an à peu près j'ai été amené à me poser cette question, une application devant passer d'un serveur ORACLE 8i à ORACLE 9i, je me suis inquiété en me disant que toutes les requêtes (surtout les OUTER JOIN) étant à l'ancienne syntaxe, il faudrait les modifier pour utiliser la syntaxe normée sinon les performances s'écrouleraient. J'ai donc fait tout un tas de tests sur des "grosses tables" (2 à 10 millions de lignes jointes avec 500 000 lignes), les requêtes étant des requêtes "du monde réel", résultat : performances identiques avec les deux méthodes, donc ORACLE sait reconnaître une jointure quelque soit la syntaxe utilisée. Nous n'avons donc pas changé les requêtes qui fonctionnent depuis un an sans dégradation de performances (Maxence : (désolé : private joke)), et bien sur, pour les nouvelles, nous utilisons la syntaxe normée, qui si elle n'est pas plus performante est au moins :
    1) normée
    2) largement plus lisible (même si j'avais depuis longtemps pris l'habitude de mettre les conditions de jointures avant les conditions fonctionnelles).

    Hope this Help
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  5. #5
    Membre à l'essai
    Inscrit en
    Septembre 2002
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    Salut,

    Lorsque je retire datepart(dw,datejour), j'obtient un msg qui dit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Serveur : Msg 8120, Niveau 16, État 1, Ligne 1
    La colonne 'r.DateJour' n'est pas valide dans la liste de sélection parce qu'elle n'est pas contenue dans une fonction d'agrégation ou dans la clause GROUP BY.
    Je crois savoir que le group by doit regrouper toutes les colonnes de select.

  6. #6
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    J'ai répondu trop vite, il faut aussi l'enlever de la liste des SELECT (sélectionner le jour n'a pas de sens, puisque tu veux la semaine entière), et ajouter un MAX à tous tes CASE WHEN (qui ne changera rien car il n'y a qu'une seule réponse, mais c'est imposé par la syntaxe du GROUP BY)
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  7. #7
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Médiat : merci pour les infos mais j'ai encore un petite question => les constats que tu décrits pour ORACLE s'appliquent-t'ils aussi pour tous les autres SGBD ?
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  8. #8
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Citation Envoyé par Magnus
    les constats que tu décrits pour ORACLE s'appliquent-t'ils aussi pour tous les autres SGBD ?
    N'ayant pas eu l'occasion de faire des test avec d'autres moteurs, je ne peux être formel, mais je dirais volontiers que les moteurs ayant introduit la syntaxe normée depuis peu (mais ce n'est pas limitatif) devraient fonctionner ainsi (si il fallait tout ré-écrire, ce serait un excellent argument pour ne pas migrer).

    Il me semble que SQLPro disait qu'il y a une différence avec SQLServer (à vérifier, surtout au niveau de la version)

    La dessus le test est facile, tu fais les deux jointures sur tes deux plus grosses tables avec des contraintes hors jointures très restrictives et tu regardes la différence de performance (attention aux effets de cache dans ce genre de test)
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  9. #9
    Membre à l'essai
    Inscrit en
    Septembre 2002
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    j'ai fait 2 choses:
    1- j'ai enlevé datejour dans le group by et dans le select, voici le msg reçu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Serveur : Msg 8120, Niveau 16, État 1, Ligne 1
    La colonne 'r.DateJour' n'est pas valide dans la liste de sélection parce qu'elle n'est pas contenue dans une fonction d'agrégation ou dans la clause GROUP BY.
    2- j'ai ajouté MAX à case when et supprimer la clause group by de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    select r.numcarte,r.nomprenoms,r.heureentree,r.heuresortie,datepart(wk,r.datejour)as 'semaine',
        CASE datepart(dw,datejour) WHEN 1 THEN MAX(r.heureentree+''+r.heuresortie) END AS Lundi,
        CASE datepart(dw,datejour) WHEN 2 THEN MAX(r.heureentree+''+r.heuresortie) END AS Mardi,
        CASE datepart(dw,datejour) WHEN 3 THEN MAX(r.heureentree+''+r.heuresortie) END AS Mercredi,
        CASE datepart(dw,datejour) WHEN 4 THEN MAX(r.heureentree+''+r.heuresortie) END AS Jeudi,
        CASE datepart(dw,datejour) WHEN 5 THEN MAX(r.heureentree+''+r.heuresortie) END AS Vendredi
    from resultatsfin r
    INNER JOIN employes e ON (r.numcarte = e.emp_numero_badge AND datepart(wk,r.datejour)='1')
    Voici le msg reçu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Serveur : Msg 8120, Niveau 16, État 1, Ligne 1
    La colonne 'r.numcarte n'est pas valide dans la liste de sélection parce qu'elle n'est pas contenue dans une fonction d'agrégation ou dans la clause GROUP BY.
    et cela pour toutes les colonnes de select.

  10. #10
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Essaye :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT r.numcarte,r.nomprenoms,datepart(wk,r.datejour) as 'semaine', 
           MAX(CASE datepart(dw,datejour) WHEN 1 THEN r.heureentree+''+r.heuresortie END) AS Lundi, 
           MAX(CASE datepart(dw,datejour) WHEN 2 THEN r.heureentree+''+r.heuresortie END) AS Mardi, 
           MAX(CASE datepart(dw,datejour) WHEN 3 THEN r.heureentree+''+r.heuresortie END) AS Mercredi, 
           MAX(CASE datepart(dw,datejour) WHEN 4 THEN r.heureentree+''+r.heuresortie END) AS Jeudi, 
           MAX(CASE datepart(dw,datejour) WHEN 5 THEN r.heureentree+''+r.heuresortie END) AS Vendredi 
    FROM resultatsfin r INNER JOIN employes e ON r.numcarte = e.emp_numero_badge 
    WHERE datepart(wk,r.datejour)='1'
    GROUP BY r.numcarte,r.nomprenoms,datepart(wk,r.datejour)
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  11. #11
    Membre à l'essai
    Inscrit en
    Septembre 2002
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    Merci infiniment !!!
    ça marche à merveille.

  12. #12
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    C'est noté, merci pour les infos Médiat.
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

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

Discussions similaires

  1. Problème avec case when
    Par kodo dans le forum Développement
    Réponses: 5
    Dernier message: 20/12/2011, 15h35
  2. DISTINCT d'un champ combiné avec CASE WHEN
    Par ninikkhuet dans le forum Requêtes
    Réponses: 1
    Dernier message: 11/05/2010, 15h13
  3. [SQL SERVER 2005] INSERT avec CASE WHEN
    Par djilos dans le forum Développement
    Réponses: 5
    Dernier message: 16/04/2010, 14h46
  4. Requête avec Case When ..
    Par Passarinho44 dans le forum Langage SQL
    Réponses: 20
    Dernier message: 08/08/2008, 16h03
  5. Réponses: 5
    Dernier message: 26/02/2008, 12h42

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