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

Développement SQL Server Discussion :

Solution élégante pour un calcul


Sujet :

Développement SQL Server

  1. #1
    Futur Membre du Club
    Inscrit en
    Mars 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 8
    Points : 7
    Points
    7
    Par défaut Solution élégante pour un calcul
    Bonjour à tous,

    Je bloque devant un calcul dont j'aimerai trouver une solution élégante.

    J'ai une table définie comme suit :
    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
    declare @data table (DataDate smalldatetime, DataKind int, DataValue int)
    insert into @data
    select '20140101',0,2
    union
    select '20140102',0,2
    union
    select '20140103',0,2
    union
    select '20140104',1,1
    union
    select '20140105',0,2
    union
    select '20140106',2,3
    union
    select '20140107',0,2
    union
    select '20140108',0,2
    La colonne DataKind correspond au type comme suit :
    • 0 = Ajouter
    • 1 = Soustraire
    • 2 = Appliquer
    • 3 = Limiter


    J’essaie d'éviter de faire une boucle ou un curseur pour gagner en performance.
    Les 2 premier type sont simple mais j'ai un problème avec Appliquer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    declare @startdate smalldatetime, @enddate smalldatetime
     
    set @startdate = '20140101'
    set @enddate = '20141231';
     
    select sum(case datakind 
    		when 0 then DataValue
    		when 1 then DataValue*-1
    		else 0 end) 
    from @data
    where dataDate between @startdate and @enddate)
    Il faudrait que ma variable @startdate contiennent la date du dernier enregistrement de type kind=2 sur l'intervalle de date donné mais je ne sais pas comment faire cela en une seule requête.

    Pourriez vous me donner un petit coup de pouce ?

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

    Je ne comprends pas ce que vous cherchez à faire.

    Que faut-il faire pour appliquer et limiter ?


    et pourquoi :
    Il faudrait que ma variable @startdate contiennent la date du dernier enregistrement de type kind=2 sur l'intervalle de date donné mais je ne sais pas comment faire cela en une seule requête.
    Est-ce un autre besoin, ou une solution que vous envisagez pour résoudre votre problème ?

  3. #3
    Membre éprouvé
    Avatar de landry161
    Homme Profil pro
    C#,PHP,MySQL,Android...
    Inscrit en
    Juillet 2010
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : C#,PHP,MySQL,Android...

    Informations forums :
    Inscription : Juillet 2010
    Messages : 423
    Points : 1 059
    Points
    1 059
    Billets dans le blog
    1
    Par défaut
    sois plus explicite

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 772
    Points : 52 732
    Points
    52 732
    Billets dans le blog
    5
    Par défaut
    Vous n'avez pas expliquer ce que sont les opérations :
    2 = Appliquer
    3 = Limiter
    J'ai supposé que :
    2 = Appliquer = >remplacer le résultat précédent par le nombre courant
    3 = Limiter => ignorer le nombre courant et remplacer par le résultat précédent
    Vous pouvez changer cet état de fait dans le CASE...


    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
    WITH T0 AS
    (SELECT *, ROW_NUMBER() OVER(ORDER BY DataDate) AS N, 
               ROW_NUMBER() OVER(ORDER BY DataDate DESC) AS M
     FROM   @DATA),
    TR AS
    (SELECT N, M, DataValue  AS VAL
     FROM   T0
     WHERE  N = 1
     UNION ALL
     SELECT T.N, T.M, CASE DataKind 
                     WHEN 0 THEN VAL + DataValue 
    				 WHEN 1 THEN VAL - DataValue 
    				 WHEN 2 THEN DataValue 
    				 WHEN 3 THEN VAL
    			  END
     FROM   TR
            INNER JOIN T0 AS T
    		      ON TR.N = T.N-1
    )
    SELECT * 
    FROM   TR 
    WHERE  M = 1;
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Futur Membre du Club
    Inscrit en
    Mars 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Bonjour,

    Parfois ça parait clair et évident mais que dans sa propre tête :-)

    Vous n'avez pas expliquer ce que sont les opérations :
    2 = Appliquer
    3 = Limiter
    J'ai supposé que :
    2 = Appliquer = >remplacer le résultat précédent par le nombre courant
    3 = Limiter => ignorer le nombre courant et remplacer par le résultat précédent
    Vous pouvez changer cet état de fait dans le CASE...
    C'est presque ça
    0 -> Ajouter = la valeur s'ajoute à la précédente
    1 -> Soustraire = la valeur se soustrait à la précédente
    2 -> Appliquer = remplacer le résultat précédent par le nombre courant
    3 -> Limiter = remplacer le résultat précédent par le nombre courant

    Votre solution fonctionne parfaitement. Merci SQLpro :-)

    Je vais essayer de la comprendre maintenant.

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

Discussions similaires

  1. Cherche une solution pour un calcule inverse
    Par Akim13 dans le forum Mathématiques
    Réponses: 2
    Dernier message: 14/08/2013, 19h01
  2. [XL-2007] solution excel pour calculer les Pi
    Par midou0998 dans le forum Excel
    Réponses: 8
    Dernier message: 09/10/2012, 11h20
  3. Réponses: 3
    Dernier message: 14/09/2009, 08h13
  4. Réponses: 11
    Dernier message: 11/09/2008, 19h14
  5. Moyen élégant pour faire un calcul glissant
    Par _moebius_ dans le forum MATLAB
    Réponses: 7
    Dernier message: 14/06/2007, 08h48

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