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

SQL Oracle Discussion :

Somme conditionnelle selon année


Sujet :

SQL Oracle

  1. #1
    Modérateur

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    avril 2007
    Messages
    1 996
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Service public

    Informations forums :
    Inscription : avril 2007
    Messages : 1 996
    Points : 3 105
    Points
    3 105
    Par défaut Somme conditionnelle selon année
    Bonjour à tous,

    je me bats avec une requête depuis pas mal de temps sans en venir à bout.
    Je fais donc appel à vous.

    J'utilise le jeu de données suivant :
    DATE TYPE VALUE
    31/12/2016 0 100
    15/05/2017 0 50
    30/09/2017 0 30
    15/05/2018 0 50
    30/09/2018 0 30
    15/10/2018 1 50
    15/10/2018 2 0

    Je cherche à faire la somme, par année, du champ VALUE.
    Jusque là pas de problème.

    Cependant, les lignes dont le TYPE est égal à 1 ou 2 ne doivent être inclues dans la somme que si elles ne sont pas les dates MAX de l'année.
    Dans le jeu de données au dessus, les résultats attendus sont donc :
    PERIODE DU AU SOMME
    2018 01/10/2017 30/09/2018 80
    2017 01/01/2017 30/09/2017 80
    2016 01/01/2016 31/12/2016 100
    2015 00/01/1900 31/12/2015 100
    --> les lignes du 15/10/2018 sont exclues car elles sont les dates max de 2018 et leur type est différent de 0.

    Si j'avais eu le jeu de données suivant :
    DATE TYPE VALUE
    31/12/2016 0 100
    15/05/2017 0 50
    30/09/2017 0 30
    15/05/2018 0 50
    30/09/2018 0 30
    15/10/2018 1 50
    15/10/2018 2 0
    16/10/2018 0 1
    Alors les lignes du 15/10/2018 auraient dû être incluses et les résultats auraient été les suivants :
    PERIODE DU AU SOMME
    2018 01/10/2017 30/09/2018 131
    2017 01/01/2017 30/09/2017 80
    2016 01/01/2016 31/12/2016 100
    2015 00/01/1900 31/12/2015 100

    Je ne vois pas comment procéder pour exclure les lignes de TYPE 1 ou 2 si elles sont les dates max d'une année mais les inclure dans ma somme dans le cas contraire.

    Si vous avez des idées, je suis preneur.

    Merci d'avance.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    janvier 2009
    Messages
    4 357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : janvier 2009
    Messages : 4 357
    Points : 10 302
    Points
    10 302
    Par défaut
    Bonjour,
    Je verrai bien un truc du genre:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    from Latable
    where type = 0 or (type in (1,2) and exists(select 1 from LaTable as sl where year(sl.date) = year(LaTable.date) and sl.date > latable.date))
    Bref je prends les lignes si le type = 0, ou s'il vaut 1 ou 2 et qu'il existe une ligne avec la même année, mais une date ultérieure. Par contre j'ai "un peu" peur pour les performances…

    Tatayo.

  3. #3
    Modérateur

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    avril 2007
    Messages
    1 996
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Service public

    Informations forums :
    Inscription : avril 2007
    Messages : 1 996
    Points : 3 105
    Points
    3 105
    Par défaut
    Merci pour l'aide.

    Il est possible que j'ai mal adapté la proposition mais les résultats que j'ai ne sont pas bons.
    Les lignes avec TYPE in (1,2) sont prises en compte même si elles sont les dates max de l'année.

    Pour plus de précision, j'ai également un "ID USER" dans ma table qui référence un utilisateur dans la table idoine.

    J'essaye de voir comment il se possible de procéder avec des CTE mais je bloque.
    1 - identifier la date max de type 0 pour chaque année
    2 - identifier toutes les lignes concernant un user
    3 - sommer la champ VALUE pour les lignes contenues entre MAX DATE x et MAX DATE x-1 via une récursive
    --> mais j'avoue que je bloque pour le moment et je me demande ce que ça pourrait bien donner côté perfs...

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    janvier 2009
    Messages
    4 357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : janvier 2009
    Messages : 4 357
    Points : 10 302
    Points
    10 302
    Par défaut
    Je pense que j'ai fait une petite erreur:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    from Latable
    where type = 0 or (type in (1,2) and exists(select 1 from LaTable as sl where year(sl.date) = year(LaTable.date) and sl.date > latable.date and s1.type = 0))
    Il faut vérifier dans la sous-requête le type de ligne. Sinon dans le premier exemple la ligne de type 1 sera prise en compte.
    De même, si pour une date donnée j'ai une ligne de type 0 et une ligne de type 1, les deux pour la dernière date de l'année, est-ce que la ligne de type 1 doit être prise en compte ? Si oui, il faut remplacer > par >= dans la sous-requête.

    Tatayo.

  5. #5
    Membre expert
    Homme Profil pro
    Inscrit en
    septembre 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : septembre 2006
    Messages : 2 720
    Points : 3 846
    Points
    3 846
    Par défaut
    Faites un CTE où vous calculez year, max(date) ,
    ensuite vous sélectionnez les données du jeu original dont le couple (year,date) n'est pas dans le CTE si de type 1 ou 2
    union all
    celles qui sont de type 0,
    c'est votre nouveau jeu de données pour calculez votre solution finale.

  6. #6
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    décembre 2013
    Messages
    3 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : décembre 2013
    Messages : 3 076
    Points : 7 013
    Points
    7 013
    Par défaut
    Si en 2018, on a ça :
    15 juin , type 0 , montant 100
    15 juillet, type 1 , montant 110
    15 août, type 2, montant 120
    15 septembre, type 1, montant 130

    Que doit-on obtenir ? 100, ou 210, ou 330 ?
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

Discussions similaires

  1. [XL-2007] Somme conditionnelle selon cellule
    Par merlinus3000 dans le forum Excel
    Réponses: 2
    Dernier message: 19/07/2013, 13h26
  2. Branchement conditionnel selon le navigateur
    Par thomzon dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 17/04/2007, 17h48
  3. Mise en forme conditionnelle selon 2 critères
    Par nadia81 dans le forum Excel
    Réponses: 4
    Dernier message: 15/01/2007, 18h14
  4. Conditionnel selon comparaison
    Par syldudu dans le forum Access
    Réponses: 3
    Dernier message: 19/09/2006, 12h28
  5. Réponses: 2
    Dernier message: 05/02/2006, 23h26

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