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 :

Group By Date et multiples IDs


Sujet :

Langage SQL

  1. #1
    Membre confirmé Avatar de joKED
    Profil pro
    Imposteur en chef
    Inscrit en
    Février 2006
    Messages
    337
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Imposteur en chef

    Informations forums :
    Inscription : Février 2006
    Messages : 337
    Points : 458
    Points
    458
    Par défaut Group By Date et multiples IDs
    Bonjour à tous,

    Je m'arrache un peu les cheveux sur ce problème.
    Voici le détail de la table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE T_TEST (
    	SomeId bigint primary key identity, -- Un Id tout simple
    	DateHeure datetime NOT NULL, -- Une date d'insertion
    	EventId bigint NOT NULL, -- Un Id d'event
    	EventValue bit NOT NULL, -- Une valeur booléenne
    	EstVisibleDansRequete varchar(50) NOT NULL -- Un champs présent juste pour la requete afin de savoir si on est ok
    )
    Insérons quelques données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 1,0,'non')
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 1,1,'non')
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 1,0,'non')
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 1,1,'oui')
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 2,0,'non')
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 2,1,'non')
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 2,1,'oui')
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 3,1,'oui')
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 4,0,'non')
    INSERT INTO T_TEST (DateHeure, EventId, EventValue, EstVisibleDansRequete) VALUES (GETDATE(), 4,1,'oui')
    Je cherche à obtenir, pour chaque EventId, l'EventValue inséré le dernier.

    Concrètement, j'ai essayé de la sorte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(DateHeure), EventId FROM T_Test GROUP BY EventId
    On est d'accord, ça fonctionne plutôt bien, et ce n'est pas difficile.

    Seulement, j'ai besoin aussi de l'EventValue (en fait, j'ai besoin de tous les champs de la table).
    J'ai donc essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(DateHeure), EventId, EventValue FROM T_Test GROUP BY EventId, EventValue
    Et bien évidemment, ça ne renvoie pas les résultats que j'attends (puisque je me retrouve avec un group by à la fois par EventId et EventValue).

    Et à partir de là, je suis perdu, je ne sais clairement pas comment m'y prendre.

    Avez vous une idée ?

    Le résultat attendu, d'après les données insérées plus haut, ne devrait contenir que les lignes dont la colonne EstVisibleDansRequete a pour valeur 'oui' (ne trichez pas, cette colonne n'est là que pour illustrer mon propos )

    Merci d'avance de votre aide.
    Tant va la cruche à l'eau qu'à la fin y'a plus d'eau.

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

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    bonjour

    Il faut passer par une sous-requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Select * FROM
       (SELECT MAX(DateHeure) AS MAXI, EventId, EventValue FROM T_Test GROUP BY EventId) As SEL
     INNER JOIN T_Test ON T_Test.EventId = Sel.EventId AND T_Test.DateHeure = SEL.Maxi
    a+
    olivier
    Merci d'ajouter un sur les tags qui vous ont aidé

  3. #3
    Membre confirmé Avatar de joKED
    Profil pro
    Imposteur en chef
    Inscrit en
    Février 2006
    Messages
    337
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Imposteur en chef

    Informations forums :
    Inscription : Février 2006
    Messages : 337
    Points : 458
    Points
    458
    Par défaut
    Malheureusement, non, la colonne EventValue dans la sous requête n'étant pas contenue dans une fonction d'aggrégation ou dans la clause GROUP BY, ça ne fonctionne pas.
    Tant va la cruche à l'eau qu'à la fin y'a plus d'eau.

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Parmi les résulotions de ce problème, il y a celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    select  tst.*
    from    t_test  tst
    where   exists
            (   select  null
                from    t_test  sel
                where   tst.EventId     = sel.EventId
                having  tst.DateHeure   = max(sel.DateHeure) 
            )
    ;
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

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

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    peux tu présenter dans un petit tableau les résultats que tu attends ?

    Et une clause WHERE filtrant que les 'OUI' ou HAVING selon le besoin ?
    Merci d'ajouter un sur les tags qui vous ont aidé

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Ou bien par une fonction de fenêtrage si supportée par le SGBDR, qui sera probablement plus performante :

    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 CTE AS (
        SELECT 
            SomeId 
    	,DateHeure 
    	,EventId 
    	,EventValue 
    	,EstVisibleDansRequete 
            ,ROW_NUMBER() OVER(PARTITION BY EventId ORDER BY DateHeure DESC) AS Rn
        FROM T_TEST 
    )
        SELECT 
            SomeId 
    	,DateHeure 
    	,EventId 
    	,EventValue 
        FROM CTE
        WHERE EstVisibleDansRequete = 'oui'
        AND Rn = 1
    ;

  7. #7
    Membre confirmé Avatar de joKED
    Profil pro
    Imposteur en chef
    Inscrit en
    Février 2006
    Messages
    337
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Imposteur en chef

    Informations forums :
    Inscription : Février 2006
    Messages : 337
    Points : 458
    Points
    458
    Par défaut
    Merci al1_24, ça fonctionne effectivement comme attendu. Je n'avais pas du tout pensé au test d'existence tel que présenté.
    Tant va la cruche à l'eau qu'à la fin y'a plus d'eau.

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

Discussions similaires

  1. Group by date sans les heures: minutes: secondes
    Par KING_OF_GRACELAND dans le forum SQL
    Réponses: 13
    Dernier message: 13/03/2008, 10h37
  2. Groupe d'option à choix multiple ?
    Par Flow56 dans le forum IHM
    Réponses: 7
    Dernier message: 09/05/2007, 16h17
  3. Group by date dans un select
    Par lampre dans le forum Requêtes
    Réponses: 4
    Dernier message: 04/09/2006, 11h16
  4. Réponses: 7
    Dernier message: 23/09/2005, 20h58
  5. Group by date
    Par cdlr27 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 14/06/2004, 09h33

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