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 :

Tracer les dates de changements de données dans une table


Sujet :

Langage SQL

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 8
    Points : 5
    Points
    5
    Par défaut Tracer les dates de changements de données dans une table
    Bonjour,

    j'ai un problème pour trouver les dates de changements de données :
    voici la structure d'une table qui représente
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    col_pk     begin_date         ca_val
    100         01/01/2010         10
    100         02/01/2010         10
    100         03/01/2010         12
    100         04/01/2010         15
    100         06/01/2010         10
    Le but est de trouver pour chaque col_pk les dates de changements de valeurs ca_val.
    On devrait obtenir le résultat suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    col_pk     begin_date         ca_val
    100         01/01/2010         10
    100         03/01/2010         12
    100         04/01/2010         15
    100         06/01/2010         10
    Merci pour votre aide

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Avec un SGBD respectant la norme (donc pas mysql) il suffit d'utiliser LEAD / LAG dans une sous requête, quel est le SGBD ?
    Le lien est donné à titre d'exemple il n'est pas spécifique à Oracle.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Avec un SGBD respectant la norme (donc pas mysql) il suffit d'utiliser LEAD / LAG dans une sous requête, quel est le SGBD ?
    Le lien est donné à titre d'exemple il n'est pas spécifique à Oracle.
    le sgbd est MSSQL

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Les fonctions LEAD / LAG ont été implémentées à partir de SQL-Server 2012.
    Quelle version utilisez-vous ?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Les fonctions LEAD / LAG ont été implémentées à partir de SQL-Server 2012.
    Quelle version utilisez-vous ?
    il faut que la query puisse fonctionner aussi bien sur un environnement sql 2005 que sql 2012...

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    On peut utiliser alors un row_number pour classer les lignes par date.

    Données
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create table matable (col_pk int, begin_date date, ca_val int);
     
    insert into matable (col_pk, begin_date, ca_val) values
    (100, '01/01/2010', 10),
    (100, '02/01/2010', 10),
    (100, '03/01/2010', 12),
    (100, '04/01/2010', 15),
    (100, '06/01/2010', 10);
    Requête 1
    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
    With cte_matable (col_pk, begin_date, ca_val, rn) as
    (
    select col_pk, begin_date, ca_val
         , row_number() over(partition by col_pk order by begin_date asc)
      from matable
    )
        select t1.col_pk, t1.begin_date, t1.ca_val
          from cte_matable as t1
     left join cte_matable as t2
            on t2.col_pk = t1.col_pk
           and t2.rn     = t1.rn - 1
         where t2.col_pk is null
            or t2.ca_val <> t1.ca_val;
     
    COL_PK  BEGIN_DATE  CA_VAL
    ------  ----------  ------
       100  2010-01-01      10
       100  2010-03-01      12
       100  2010-04-01      15
       100  2010-06-01      10
    Requête 2
    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
    With cte_matable (col_pk, begin_date, ca_val, rn) as
    (
    select col_pk, begin_date, ca_val
         , row_number() over(partition by col_pk order by begin_date asc)
      from matable
    )
    select t1.col_pk, t1.begin_date, t1.ca_val
      from cte_matable as t1
     where not exists (select null
                         from cte_matable as t2
                        where t2.col_pk = t1.col_pk
                          and t2.rn     = t1.rn - 1
                          and t2.ca_val = t1.ca_val);
     
    COL_PK  BEGIN_DATE  CA_VAL
    ------  ----------  ------
       100  2010-01-01      10
       100  2010-03-01      12
       100  2010-04-01      15
       100  2010-06-01      10

  7. #7
    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,

    Pour les versions avant 2012, vous pouvez aussi émuler LEAD/LAG de la sorte :

    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
    29
    30
     
    WITH CTE AS (
    	SELECT 
    			col_pk     
    		,	begin_date         
    		,	ca_val
    		,	ROW_NUMBER() OVER(PARTITION BY col_pk ORDER BY begin_date) AS Rn
    	FROM LaTable
    )
    ,tmp AS (
    SELECT 
    		col_pk     
    	,	begin_date         
    	,	ca_val
    	,	Rn
    	,	CASE 
    			WHEN Rn%2 = 1 THEN 
    				MAX(CASE WHEN Rn%2 = 0 THEN ca_val END) OVER (PARTITION BY col_pk, (Rn) / 2)
    			ELSE 
    				MAX(CASE WHEN Rn%2 = 1 THEN ca_val END) OVER (PARTITION BY col_pk, (Rn+1) / 2)
    		END AS Precedent
    FROM CTE
    )
    SELECT 		
    		col_pk     
    	,	begin_date         
    	,	ca_val
    FROM	tmp
    WHERE	Precedent <> ca_val 
    	OR	Precedent IS NULL

  8. #8
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Pourquoi pas juste un "min" ?

    Bon, ok, ça ne marque que si on est sûr qu'après une modification, le prix ne redevient jamais initial :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select col_pk, min(begin_date), ca_val
    from latable
    group by col_pk, ca_val
    On ne jouit bien que de ce qu’on partage.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Merci Waldar & aieeeuuuuu, c'est exactement cela

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

Discussions similaires

  1. [Access 2007] changement de donnée dans une zone de liste
    Par Jerez62 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 02/09/2008, 13h09
  2. recherche date de maj de données dans une table
    Par Switch03 dans le forum SQL
    Réponses: 5
    Dernier message: 05/03/2008, 13h15
  3. Réponses: 5
    Dernier message: 10/12/2007, 16h15
  4. Réponses: 14
    Dernier message: 29/11/2007, 07h47
  5. inserrtion des données dans une table via les servlets
    Par melleweb dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 28/11/2007, 10h53

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