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 :

Comment écrire une requête avec des "rolling periods" ?


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut Comment écrire une requête avec des "rolling periods" ?
    Bonsoir,

    Désolé pour le titre pas très explicite. Imaginons une table "Facture" avec un simple champ "Montant" et un champ "Date". Je souhaiterais, dans un but d'analytics, écrire une requête qui me calculerait la somme/moyenne/whatever sur les n derniers jours, pour les n derniers jours.

    Par exemple, avec les données suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Date             Montant
    06-07-2014    10
    05-07-2014    5
    04-07-2014    15
    03-07-2014    10
    02-07-2014    10
    01-07-2014    15
    Disons que, pour les 4 derniers jours, je souhaite calculer la somme des 3 derniers jours, je souhaite donc obtenir le résultat suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Date             Résultat
    06-07-2014    10 + 5 + 15 = 30
    05-07-2014    5 + 15 + 10 = 30
    04-07-2014    15 + 10 + 10 = 35 
    03-07-2014    10 + 10 + 15 = 35
    Calculer ce résultat pour une seule date est triviale, mais je me demande comment réaliser ça de manière efficace sans avoir à faire autant de requêtes que je souhaites de data point (ni même si c'est possible).

    Merci !

  2. #2
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 063
    Par défaut
    Bonjour,

    Avec des fonctions de fenêtrage, c'est possible. Encore faut-il que votre SQBD les implémente, mais vous ne le précisez pas...
    Quel SGBD utilisez-vous ?
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  3. #3
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    Bonjour,

    J'utilise actuellement MySQL. J'ai la possibilité d'utiliser PostgreSQL également, mais je préférerais rester sur MySQL pour certaines raisons spécifiques au projet .

  4. #4
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 063
    Par défaut
    Si vous restez sous MySQL, pas de fonctions de fenêtrage... Alors que c'est possible avec PostgreSQL.
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  5. #5
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    Merci. Je vais essayer de voir du côté de cette fonctionnalité sur postgre alors .

  6. #6
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    Ca semble très intéressant en tout cas ! J'ai fait un petit test avec une table contenant une dizaine de valeurs, par jour, et je souhaite calculer pour les trois derniers jours, la somme des trois jours précédents en chaque point. J'ai écrit la requête suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT date, SUM(amount) OVER (ORDER BY date) AS amount FROM foo WHERE date >= '2014-07-05';
    Ca marche bien pour la date 2014-07-07 (qui fait la somme des trois précédents), par contre 2014-07-06 ne fait la somme que des montants du 6 et du 5, et le 5 ne fait que la somme que de lui même, en ignorant les valeurs avant.

    De la même manière, d'un point de vue performance comment ce genre de requêtes se comportent ? J'essaye d'évaluer plusieurs solutions, car grosso modo, je souhaite calculer des analytics, pour la plupart en utilisant ce modèle de "rolling periods", et souvent sur des périodes mensuelles. Certains mois, je peux avoir avoir jusqu'à 40 000 entrées à additionner (soit pas mal d'entrées sur 3 ou 4 ans, et la somme est de ce fait trop longue). Est-ce que le fait d'utiliser ces partitions permet d'améliorer les performances ?

    EDIT : ça semble fonctionner ainsi :

    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
        date,
        amount,
    	rolling
    from
    	(
    		SELECT 
    			date, 
    			amount,
    			sum(amount) over(partition by null order by date rows 2 preceding) rolling
    		FROM foo
    	) AS sq
    where date >= '2014-07-05'
    order by date;
    Est-ce la manière la plus efficace ?

    EDIT 2: réarrangé pour tenir compte du fait que, par jour, il puisse y avoir plusieurs valeurs :

    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
    	date,
    	daily_amount,
    	rolling
    FROM
    	(
    		SELECT
    			date,
    			SUM(amount) as daily_amount,
    			SUM(SUM(amount)) OVER(ORDER BY date ROWS 2 PRECEDING) rolling
    		FROM foo
    		GROUP BY date
    	) AS sq
    WHERE date >= '2014-07-05';
    EDIT 3 : maintenant le problème consiste à modifier cette requête pour avoir des valeurs pour les jours ou il n'y a rien. Par exemple, si je n'ai pas de ligne le 2014-06-30, j'aimerais quand même avoir la somme pour les 30 jours précédents (en considérant que, ce jour-ci, amount est équivalent de 0). De la même manière, si je dispose d'une ligne pour 2014-07-05 d'un montant 50 et une pour 2014-07-08 d'un montant 10, si je souhaite calculer sur les 3 derniers jours, je souhaite avoir pour 2014-07-08 le résultat 10, et non 50 (ce qui est le cas avec la requête actuelle qui sélectionne les ROWS 3 PRECEDING

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

Discussions similaires

  1. [OpenOffice][Tableur] Comment écrire une macro avec 2 variables et enregistrement des résultats du calcul
    Par Pascaltech dans le forum OpenOffice & LibreOffice
    Réponses: 9
    Dernier message: 09/09/2015, 18h00
  2. [PHP-JS] Comment créer une boucle avec des headers
    Par djinnwatcher dans le forum Langage
    Réponses: 10
    Dernier message: 17/07/2006, 15h48
  3. Réponses: 2
    Dernier message: 03/05/2006, 17h00
  4. [SQL] Requête dans une requête...avec des INNER JOIN!
    Par PedroBD dans le forum PHP & Base de données
    Réponses: 18
    Dernier message: 06/04/2006, 08h26
  5. [ABAP] Comment créer une requête avec jointure
    Par roadster62 dans le forum SAP
    Réponses: 1
    Dernier message: 21/02/2006, 16h04

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