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 :

séquencement des dates et changement id


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 16
    Points
    16
    Par défaut séquencement des dates et changement id
    Bonjour,
    j'ai une table qui à chaque fois qu'un élément est produit ,elle crée un champs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    identifient du Produit    | quantité     | date
    1012                      |    1         | 24/04/2009 10:32:00
    1012                      |    1         | 24/04/2009 10:33:00
    1011                      |    1         | 24/04/2009 10:34:00
    1011                      |    1         | 24/04/2009 10:35:00
    1011                      |    1         | 24/04/2009 10:36:00
    1012                      |    1         | 24/04/2009 10:37:00
    1012                      |    1         | 24/04/2009 10:38:00
    1012                      |    1         | 24/04/2009 10:39:00
    1012                      |    1         | 24/04/2009 10:40:00
    (je ne peux pas la modifier)

    Je voudrais savoir quelle requête SQL pour avoir ce résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1012                      |   1         |24/04/2009 10:37:00
    c'est à dire quand se produit le changement de produit.

    sachant que le 1012 peut avoir été produit avant le 1011.
    mais je veux la date de début du dernier produit encours.

    Et tous ça pour faire la somme des quantités soit :
    Merci

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Bonjour,

    Merci de préciser au minimum votre sgbd, et au passage de lire ce post : http://www.developpez.net/forums/a69...gage-sql-lire/

  3. #3
    Membre à l'essai
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 16
    Points
    16
    Par défaut
    oui,
    c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Microsoft SQL Server  2000 - 8.00.760 (Intel X86)  
     Dec 17 2002 14:22:05   
    Copyright (c) 1988-2003 Microsoft Corporation  
    Enterprise Edition on Windows NT 5.0
    (Build 2195: Service Pack 4)

  4. #4
    Membre confirmé Avatar de agemis31
    Profil pro
    DBA
    Inscrit en
    Octobre 2007
    Messages
    399
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : DBA

    Informations forums :
    Inscription : Octobre 2007
    Messages : 399
    Points : 478
    Points
    478
    Par défaut GROUP BY
    Bonjour,

    Vous pouvez regrouper par produit (GROUP BY) et calculer la somme (SUM) de la colonne quantité des lignes regroupées.

    Pour obtenir le dernier produit, vous pouvez utiliser MAX sur la date.

    @+

  5. #5
    Membre à l'essai
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 16
    Points
    16
    Par défaut Group by et max
    c'est plus complexe que ça :
    je ne veux que la somme des derniers produits ici c'est le 1012.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    identifient du Produit     | Sum(quantité)
    1012                       |   4
    Et non la somme de tous les 1012.(Dans l'exemple ci-dessus)

    Et pour le max : je sais identifier le produit en cours.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Vous n'avez pas decrit votre table, supposons que vous ayez une table PRODUCTION (id_produit, quantite, date_prod).
    SQL Server accepte les fonction analytiques.

    Vous pouvez selectionner l'identifiant du produit et la somme des quantité à partir du dernier changement de production.
    Pour obtenir les changements de production, vous pouvez utiliser lag() pour récupérer le id_produit précédent ordonné par date, pour ne conserver que les lignes dont le id_produit est différent du précédent, et enfin ne conserver que l'heure du dernier changement avec un max :
    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
    select 
         id_produit,
         sum(quantite) as quantite_totale
    from production
    where date_prod >=
          (
           select
                max(date_prod) as date_dernier_changement
           from
                (
                 select 
                      id_produit, 
                      date_prod, 
                      lag(id_produit) over (order by date_prod) as prod_precedent
                 from production
                )
           where id_produit <> coalesce(prod_precedent,0)
          )
    group by id_produit
    Quand je vois ma requête, je me dis que c'est pas très elegant, il doit y avoir plus simple. Ceci dit ça fonctionne

    EDIT : Par contre, si lors d'un changement de production l'heure est la même pour les deux produits, la requête remontera les deux produits... donc si ça peut arriver, il faudra limiter le résultat au dernier produit en date.

  7. #7
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Si j'ai bien compris, ton critère de "rupture" est le produit, ton critère de tri est la date, c'est ça ?

    Si je me plante pas, SQL Server 2000 ne dispose pas des fonctions analytiques... donc c'est balot.

    Voyons les chose simplement. Ce que tu veux, c'est comparer chaque ligne avec la ligne précédente pour savoir si c'est le même produit, non ?
    Or le précédent d'une ligne, c'est celui dont la date est la plus élevée parmi les lignes dont la date lui est inférieure (la borne sup comme on dit en général)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT *
    FROM TaTable a 
      JOIN TaTable b ON b.date < a.date
    WHERE date = (SELECT max(date)
                         FROM TaTable b 
                         WHERE b.date < a.date)
    En ajoutant dans le WHERE : a.id <> b.id, tu obtiens les ruptures.
    Or ces ruptures définissent des intervalles de temps sur les lesquels tu auras les séquences de produit identiques.

    => Tu prends cet ensemble de ruptures et tu le joins avec lui-même afin de définir les intervalles [date1, date2]

    Enfin, tu joins cet ensemble de lignes avec ta table de départ en regroupant par interval (ce qui te permet de compter).

    Tu vois à peu près ?

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Citation Envoyé par pacmann Voir le message
    Si je me plante pas, SQL Server 2000 ne dispose pas des fonctions analytiques... donc c'est balot.
    Coup dur, ma solution est à jeter

  9. #9
    Membre à l'essai
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 16
    Points
    16
    Par défaut lag et SQlserveur
    Le lag() ne fonctionne pas dans mon SQLseveur.
    Il ne peux y avoir deux production la même 'heure'.
    Peut-être avec Oracle?

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Oui, Oracle accepte ce type de fonctions, depuis la 8i me semble-t-il.

  11. #11
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    La reponse de PacMan est une bonne voie pour votre requete je pense.

    bon courage
    Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)

  12. #12
    Membre à l'essai
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 16
    Points
    16
    Par défaut Beau mais ne marche pas
    c'est vraie que c'est beau.
    Mais ça ne fonctionne pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT *
    FROM TaTable a 
      , TaTable b 
    WHERE  b.date < a.date and date = (SELECT max(date)
                         FROM TaTable b 
                         WHERE b.date < a.date) and a.id <>b.id
    Bon je vais le faire en code!
    Merci

  13. #13
    Modérateur
    Avatar de Chtulus
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2008
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2008
    Messages : 3 094
    Points : 8 678
    Points
    8 678
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FROM TaTable a 
      , TaTable b


    Et la jointure est passée où ?


    « Je ne cherche pas à connaître les réponses, je cherche à comprendre les questions. »
    - Confucius -

    Les meilleurs cours, tutoriels et Docs sur les SGBD et le SQL
    Tous les cours Office
    Solutions d'Entreprise



  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Qu'est ce qui ne fonctionne pas?

    Cette requête te renvoie les changement de production :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT *
    		FROM production a 
    		  JOIN production b ON b.date_prod < a.date_prod
    		WHERE b.date_prod = (SELECT max(date_prod)
    		                     FROM production b 
    		                     WHERE b.date_prod < a.date_prod)
    		AND a.id_produit <> b.id_produit
    A partir de là, pour obtenir le resultat que tu voulais, il n'y a plus grand chose à faire :
    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
    select 
         id_produit,
         sum(quantite) as quantite_totale
    from production
    where date_prod >=
          (
           SELECT max(a.date_prod)
    		FROM production a 
    		  JOIN production b ON b.date_prod < a.date_prod
    		WHERE b.date_prod = (SELECT max(date_prod)
    		                     FROM production b 
    		                     WHERE b.date_prod < a.date_prod)
    		AND a.id_produit <> b.id_produit
          )
    group by id_produit

  15. #15
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Snipah,

    Si je ne me trompe pas, tu as oublié l'étape "définir les intervalles".
    Ce qui nécessite de réutiliser la méthode de séquencement...
    (c'est pas pour rien que je n'ai pas donné directement le résultat : c'est chiant à écrire )

    En plus, c'est une catastrophe au niveau perfs. Le mieux serait de passer par une table temporaire (je suppose que contrairement à Oracle, SQL Server ne matérialise pas sur les éventuelles CTE).

    Enfin bon, notre amis à raison : sans les fonctions analytiques, il vaut mieux le faire en COBOL !!

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  16. #16
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    Allez je me lance, quelque chose du genre

    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
     
    SELECT   c.ladate ,
             c.id_prod,
             SUM(matable.qte)
    FROM     matable
             INNER JOIN
                      ( SELECT b.ladate,
                              b.id_prod
                      FROM
                              ( SELECT  b.id_prod,
                                       MIN(b.ladate) ladate
                              FROM     matable a
                                       INNER JOIN matable b
                                       ON
                                                (
                                                         a.id_prod<>b.id_prod
                                                     AND b.ladate  >a.ladate
                                                )
                              GROUP BY b.id_prod
                              ) b
                      HAVING  b.ladate=MAX(b.ladate)
                      ) c
             ON
                      (
                               matable.ladate>=c.ladate
                      )
    GROUP BY c.ladate,
             c.id_prod
    A adapter
    Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)

  17. #17
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Citation Envoyé par pacmann Voir le message
    Snipah,

    Si je ne me trompe pas, tu as oublié l'étape "définir les intervalles".
    Ce qui nécessite de réutiliser la méthode de séquencement...
    (c'est pas pour rien que je n'ai pas donné directement le résultat : c'est chiant à écrire )
    C'est vrai, mais comme il ne veut que le dernier, on prend la date du dernier changement, et on récupère de notre table les lignes dont la date est supérieure ou égale.

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

Discussions similaires

  1. [WD18] [62h] Changement comportement initialisation des dates
    Par Arnaud B. dans le forum WinDev
    Réponses: 18
    Dernier message: 29/09/2020, 15h03
  2. [XL-2003] Macro changement couleur des dates passées
    Par Walt51 dans le forum Excel
    Réponses: 8
    Dernier message: 02/06/2014, 17h59
  3. Changement du format d'affichage des dates
    Par tchoimars dans le forum Sql Developer
    Réponses: 2
    Dernier message: 05/07/2007, 15h09
  4. Réponses: 6
    Dernier message: 21/06/2007, 15h26
  5. Réponses: 1
    Dernier message: 06/03/2007, 12h25

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