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 :

Calcul du temps de changement de référence


Sujet :

Langage SQL

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2023
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Mars 2023
    Messages : 6
    Points : 5
    Points
    5
    Par défaut Calcul du temps de changement de référence
    Bonjour,

    J'ai besoin d'aide sur une requête SQL que je dois réaliser.

    J'ai des données de production dans une table.
    Je dois extraire les temps de changement de référence.
    L'idée est de trouver les changements sur la colonne "Reference", et calculer la différence entre la date de la ref précédente et la ref suivante.

    Je voudrais le faire en SQL plutôt que par programme car le nombre de lignes est important selon la période choisie.

    J'ai des compétences limitées en SQL. Je vous remercie par avance de bien vouloir m'aider.

    Lien db-fiddle : https://www.db-fiddle.com/f/vA44ZtDk1VtWffz3w33L25/0


    Exemple :
    La table de production :

    | Date | NumLigne | Reference | NumIncremental |
    | ------------------- | -------- | --------- | -------------- |
    | 2023-03-17 08:52:10 | 3 | REF_A | 8001234 |
    | 2023-03-17 08:52:45 | 3 | REF_A | 8001235 |
    | 2023-03-17 08:53:16 | 3 | REF_A | 8001236 |
    | 2023-03-17 08:53:50 | 3 | REF_A | 8001237 |
    | 2023-03-17 08:58:20 | 3 | REF_B | 2001238 |
    | 2023-03-17 08:58:55 | 3 | REF_B | 2001239 |
    | 2023-03-17 08:59:10 | 3 | REF_B | 2001240 |
    | 2023-03-17 08:59:45 | 3 | REF_B | 2001241 |
    | 2023-03-17 09:02:30 | 3 | REF_B | 2001242 |
    | 2023-03-17 09:03:10 | 3 | REF_B | 2001243 |
    | 2023-03-17 09:10:02 | 3 | REF_C | 3001244 |
    | 2023-03-17 09:10:52 | 3 | REF_C | 3001245 |
    | 2023-03-17 09:11:30 | 3 | REF_C | 3001246 |
    | 2023-03-17 09:12:30 | 3 | REF_A | 8001247 |
    | 2023-03-17 09:13:10 | 3 | REF_A | 8001248 |
    | 2023-03-17 09:13:50 | 3 | REF_A | 8001249 |
    | 2023-03-17 09:14:30 | 3 | REF_A | 8001250 |
    | 2023-03-17 09:28:30 | 3 | REF_B | 2001251 |
    | 2023-03-17 09:29:10 | 3 | REF_B | 2001252 |


    Le résultat voulu :
    | Date changement | Reference avant| Reference après | Durée|
    | ----------------------- | ----------- | ---------- | -------------- |
    | 2023-03-17 08:58:20 | REF_A | REF_B | 4:30
    | 2023-03-17 09:10:02 | REF_B | REF_C | 6:52
    | 2023-03-17 09:12:30 | REF_C | REF_A | 1:00
    | 2023-03-17 09:28:30 | REF_A | REF_B | 14:00
    Images attachées Images attachées  

  2. #2
    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
    Comme ceci :
    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
      select DateChgt, OldRef, NewRef, Duree
        from (SELECT cast(@ReferencePre as char) as OldRef
                   , (@ReferencePre <> Reference) AS statusChanged
                   , @ReferencePre := Reference as NewRef
                   , SEC_TO_TIME(TIMESTAMPDIFF(SECOND, @DatePre, Date)) as Duree
                   , @DatePre := Date as DateChgt
                FROM production 
                   , (SELECT @ReferencePre:=NULL, @DatePre:=null) AS d
             ) t
       where statusChanged
    order by DateChgt;
     
    | DateChgt            | OldRef | NewRef | Duree    |
    | ------------------- | ------ | ------ | -------- |
    | 2023-03-17 08:58:20 | REF_A  | REF_B  | 00:04:30 |
    | 2023-03-17 09:10:02 | REF_B  | REF_C  | 00:06:52 |
    | 2023-03-17 09:12:30 | REF_C  | REF_A  | 00:01:00 |
    | 2023-03-17 09:28:30 | REF_A  | REF_B  | 00:14:00 |
    https://www.db-fiddle.com/f/vA44ZtDk1VtWffz3w33L25/2

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2023
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Mars 2023
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Merci, c'est top ce qu'on peut faire quand on maitrise.

    Ça va beaucoup m'aider.

    Bonne journée.

  4. #4
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 099
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 099
    Points : 8 208
    Points
    8 208
    Billets dans le blog
    17
    Par défaut
    Ton sqlfiddle est sous MySQL 5, au cas où tu aurais en fait MySQL 8, avec une CTE et la fonction fenêtrée LAG() :

    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
    SET @@sql_mode = 'ANSI,TRADITIONAL';
     
    WITH report AS (
    	SELECT ALL
    		CASE WHEN LAG("Reference") OVER (ORDER BY "Date" ASC) <> "Reference" THEN
    			"Date"
    		END AS "Date changement",
    		CASE WHEN LAG("Reference") OVER (ORDER BY "Date" ASC) <> "Reference" THEN
    			LAG("Reference") OVER (ORDER BY "Date" ASC)
    		END AS "Référence avant",
    		"Reference" AS "Référence après",
    		CASE WHEN LAG("Reference") OVER (ORDER BY "Date" ASC) <> "Reference" THEN
    			SEC_TO_TIME(TIMESTAMPDIFF(SECOND, LAG("Date") OVER (ORDER BY "Date" ASC), "Date"))
    		END AS "Durée changement"
    	FROM production 
    )
    SELECT ALL *
    FROM report
    WHERE "Date changement" IS NOT NULL
    ;
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2023
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Mars 2023
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Oui ca fonctionne également.

    Je vais pouvoir valider ça cette semaine avec la base de production Oracle. Je verrai quelle version fonctionne le mieux.

  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
    Vous êtes sur Oracle DB ou MySQL ?
    Votre fiddle étant sur MySQL 5 je suis parti sur cette version, mais ça ne marchera pas pour Oracle DB.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2023
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Mars 2023
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Oui je suis sous Oracle. J'ai oublié de le préciser. Je pensais que la différence était minime.
    Sur db-fiddle je n'avais pas ce choix.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2023
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Mars 2023
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    J'ai essayé sur LiveSQL.Oracle.

    J'arrive à avoir quelque chose d'à peu près équivalent avec :

    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
     
    WITH report AS (
    SELECT ALL
    		CASE WHEN LAG(Reference) OVER (ORDER BY DateHeure ASC) <> Reference THEN
    			LAG(DateHeure) OVER (ORDER BY DateHeure ASC)
    		END AS Date_Avant,
        	CASE WHEN LAG(Reference) OVER (ORDER BY DateHeure ASC) <> Reference THEN
    			DateHeure
    		END AS Date_Apres,
    		CASE WHEN LAG(Reference) OVER (ORDER BY DateHeure ASC) <> Reference THEN
    			LAG(Reference) OVER (ORDER BY DateHeure ASC)
    		END AS Reference_Avant,
        	CASE WHEN LAG(Reference) OVER (ORDER BY DateHeure ASC) <> Reference THEN
    			Reference
    		END AS Reference_Apres
    	FROM production 
    )
    SELECT Date_Avant, Date_Apres, Reference_Avant, Reference_Apres, (Date_apres-Date_Avant)*1440 as Duree
    FROM report
    WHERE Date_Avant IS NOT NULL
    ;
    Images attachées Images attachées  

  9. #9
    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
    Citation Envoyé par guillaume-info Voir le message
    Oui je suis sous Oracle. J'ai oublié de le préciser. Je pensais que la différence était minime.
    Oui rien à voir ! Ce n'est pas bien grave j'aurai appris quelque chose sur MySQL 5.

    Sur Oracle vous pouvez utiliser MATCH_RECOGNIZE :
    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 DateChgt, OldRef, NewRef, Duree
      from production
           match_recognize(partition by NumLigne
                               order by dt
                               measures dt                                    as DateChgt
                                      , prev(Reference)                       as OldRef
                                      , Reference                             as NewRef
                                      , numtodsinterval(dt - prev(dt), 'day') as Duree
                                one row per match
                                pattern ( x+ )
                                 define x as  Reference <> prev(Reference)
                          );
     
    DateChgt             OldRef  NewRef  Duree
    -------------------  ------  ------  -----------------------------
    2023-03-17 08:58:20  REF_A   REF_B   +000000000 00:04:30.000000000
    2023-03-17 09:10:02  REF_B   REF_C   +000000000 00:06:52.000000000
    2023-03-17 09:12:30  REF_C   REF_A   +000000000 00:01:00.000000000
    2023-03-17 09:28:30  REF_A   REF_B   +000000000 00:14:00.000000000

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2023
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Mars 2023
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Merci, je vais pouvoir essayer ça demain ou jeudi.

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

Discussions similaires

  1. comment calculer le temps d'execution
    Par passion_info dans le forum C++Builder
    Réponses: 1
    Dernier message: 09/06/2005, 09h13
  2. Calculer le temps passé
    Par Joeleclems dans le forum MFC
    Réponses: 4
    Dernier message: 29/04/2005, 09h40
  3. calculer le Temp écoulé
    Par ada_b dans le forum SQL
    Réponses: 1
    Dernier message: 30/11/2004, 09h44
  4. [MFC] : CTime ? Calcul de temps d'éxécution
    Par jonzuzu dans le forum MFC
    Réponses: 10
    Dernier message: 25/05/2004, 14h22
  5. Réponses: 8
    Dernier message: 18/09/2002, 03h20

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