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 :

Erreur de résultat avec la fonction last_value


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Homme Profil pro
    unix
    Inscrit en
    Septembre 2016
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Septembre 2016
    Messages : 83
    Points : 58
    Points
    58
    Par défaut Erreur de résultat avec la fonction last_value
    bonjour a tous

    je cherche a récupérer la valeur max et min d'une colonne nommé montant en utilisant les deux Functions First_value et last_value

    avec First_value ca marche bien par comptre avec last_value la résultat retourné ne répond pas a mon besoin (récupérer la valeur max)

    je doit avoir les colones encadrées en vert (voir l'imprime écran)

    Qui peut m'expliquer a quoi due ces résultats

    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
    CREATE TABLE clients
    (clientsId INT, OrderDate DATE, montant MONEY) ;
    INSERT clients VALUES
    (1, '2016-12-03', '12500')
    , (1, '2016-10-07', '15000')
    , (1, '2016-09-12', '16000')
    , (2, '2016-07-11', '900')
    , (2, '2016-09-13', '18000')
    , (2, '2016-11-03', '7500')
    , (3, '2016-01-29', '19500')
    , (3, '2016-04-19', '20000')
    , (3, '2016-07-09', '18000') ;
     
     
    select clientsId,OrderDate,montant,FIRST_VALUE(montant)over (partition by clientsId order by orderDate desc)as first_value,
    last_VALUE(montant)over (partition by clientsId order by orderDate asc)as last_value from clients
    merci pour vos aide
    Images attachées Images attachées  

  2. #2
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    C'est tout simplement parce que FIRST_VALUE et LAST_VALUE ne sont pas fait pour récupérer le minimum et le maximum d'un enregistrement, mais le premier ou le dernier.

    Alors d'accord, si les enregistrements sont triés, on peut y arriver, mais dans ce cas, il faut qu'ils soient triés sur la colonne concerné ! Ici, tu tries sur les dates pour récupérer le MIN et le MAX des montants. Forcément, ça ne peut pas marcher.

    Il y a beaucoup plus simple pour arriver à faire ce que tu veux :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select clientsId,
    	OrderDate,
    	montant,
    	MIN(montant) over (partition by clientsId ) as first_value,
    	MAX(montant) over (partition by clientsId ) as last_value 
    	from clients

    MIN et MAX sont utilisables avec le fenêtrage. Autant les utiliser. De plus, comme se sont des opérations d'agrégation qui se fiche complètement de l'ordre des enregistrements, tu peux faire sauter les clauses ORDER BY de ta partition.

    Si maintenant, le but était véritablement d'obtenir MIN et MAX à l'aide de FIRST_VALUE et LAST_VALUE, alors voici ce que tu aurais pu faire :
    Code SQL : 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
     
     
     
    select clientsId,
    	OrderDate,
    	montant,
    	FIRST_VALUE(montant) over (partition by clientsId ORDER BY montant ASC) as first_value,
    	FIRST_VALUE(montant) over (partition by clientsId ORDER BY montant DESC) as last_value 
    	from clients
     
    select clientsId,
    	OrderDate,
    	montant,
    	LAST_VALUE(montant) over (partition by clientsId ORDER BY montant DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as first_value,
    	LAST_VALUE(montant) over (partition by clientsId ORDER BY montant ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as last_value 
    	from clients
    	order by clientsId, OrderDate
     
    select clientsId,
    	OrderDate,
    	montant,
    	FIRST_VALUE(montant) over (partition by clientsId ORDER BY montant) as first_value,
    	LAST_VALUE(montant) over (partition by clientsId ORDER BY montant ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as last_value 
    	from clients

    3 exemples :
    • Le premier, avec uniquement FIRST_VALUE ;
    • Le second, avec uniquement LAST_VALUE ;
    • Le dernier, avec les deux


    Le point important à noter pour LAST_VALUE (et qui répond sans doute à la question initiale), est qu'il est nécessaire de préciser la portée de la partition lors de l'évaluation de la fonction. En effet, par défaut, la portée est toutes les lignes depuis le début de la partition jusqu'à la ligne courante. Donc, sans contre ordre, LAST_VALUE utilisera la valeur de la ligne courante à chaque fois. D'où la clause ROWS BETWEEN pour LAST_VALUE pour forcer à utiliser toutes les lignes de la partition lors de l'évaluation de la fonction.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

Discussions similaires

  1. [AC-2007] Comment récupérer 2 résultats avec 1 fonction ?
    Par tibofo dans le forum VBA Access
    Réponses: 2
    Dernier message: 04/08/2010, 17h14
  2. [Dates] Erreur de calcul avec la fonction mktime ?
    Par Xpertfly dans le forum Langage
    Réponses: 1
    Dernier message: 18/11/2008, 11h40
  3. Erreur de calcul avec la fonction log
    Par xav181 dans le forum C++
    Réponses: 8
    Dernier message: 07/04/2008, 15h08
  4. erreur de linkage avec une fonction extern
    Par ali.ensi dans le forum C
    Réponses: 5
    Dernier message: 12/03/2008, 23h23
  5. erreur avec la fonction putfile() sur connexion FTP
    Par stefane1981 dans le forum C++
    Réponses: 2
    Dernier message: 23/09/2005, 09h13

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