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 :

Variations sur NULL, ou SUM(X+Y) <> SUM(X) + SUM(Y) ? [Débat]


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 213
    Billets dans le blog
    16
    Par défaut Variations sur NULL, ou SUM(X+Y) <> SUM(X) + SUM(Y) ?
    En SQL ,Sum(X+Y) et Sum(X) + Sum(Y) ne donnent pas nécessairement le même résultat.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE TABLE T
    (X          Integer,
     Y          Integer
    ) ;
    INSERT INTO T VALUES (5, null) ;
    INSERT INTO T VALUES (0, 0) ;
     
    Select Sum(X+Y) as 'Sum(X+Y)'
    from T
     
    Select Sum(X) + Sum(Y) as 'Sum(X) + Sum(Y)'
    from T
    Avec SQL Server 2005, on obtient respectivement 0 et 5. Dur, dur...

    Qu’en est-il avec la norme ? Avec les autres SGBD ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  2. #2
    J1
    J1 est déconnecté
    Membre expérimenté Avatar de J1
    Inscrit en
    Mai 2004
    Messages
    321
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 321
    Par défaut
    Bonjour,

    sous Access 2003, j'obtiens le même résultat, ce qui me semble normal.
    En effet, contrairement à l'opérateur "+", la fonction d'agrégation SUM ignore le NULL.
    En d'autres termes, là où l'opérateur "+" va laisser se propager NULL à l'ensemble de la somme, la fonction SUM va, elle, ne sommer que les valeurs non-NULL.

    Ainsi, si l'on décompose ta première requête, le SGBD la traite ainsi :

    Etape 1
    l'opérateur "+" somme X et Y sur la première ligne :
    5 + NULL = NULL (l'opérateur "+" n'ignore pas le NULL, qui se "propage" donc)
    puis sur la deuxième ligne :
    0 + 0 = 0

    Etape 2
    la fonction SUM somme ensuite chaque sous-total :
    SUM(NULL,0) = 0 (la fonction SUM ignore le NULL, qui ne se propage donc pas)

    Le résultat final de ta première requête est donc bien 0.


    Maintenant, si on décompose ta deuxième requête, le SGBD la traite ainsi :

    Etape 1
    la fonction SUM somme les X de chaque ligne :
    SUM(5,0) = 5
    puis somme les Y de chaque ligne :
    SUM(NULL,0) = 0 (la fonction SUM ignore le NULL, qui ne se propage donc pas)

    Etape 2
    l'opérateur "+" somme ensuite le résultat de chaque SUM :
    5 + 0 = 5

    Le résultat final de ta deuxième requête est donc bien 5.


    Remarque : pour les besoins de l'explication, je représente schématiquement le fonctionnement de la fonction SUM, mais il est bien évident que sa syntaxe n'est pas réellement de la forme SUM(valeur1,valeur2).

  3. #3
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 213
    Billets dans le blog
    16
    Par défaut
    Bonjour J1,

    Merci pour votre réponse détaillée et pour avoir pris le temps de vérifier les résultats concernant Access. Notre approche est la même, car nous sommes manifestement en phase avec le raisonnement tenu par Ted Codd concernant le comportement des opérateurs arithmétiques dans le contexte d’une logique trivalente :
    x + null = null
    Vous écrivez : "la fonction SUM ignore le NULL, qui ne se propage donc pas". Mais si l’on code :
    SELECT SUM (1 + Null)
    le résultat est quand même null...

    Peu importe. Le comportement général de SQL m'incite à déclarer systématiquement les colonnes des tables comme "Not null".

    En effet, pour reprendre l'exemple de SUM, quand pour une même application, deux développeurs coderont en toute bonne foi, l'un SUM(X+Y) et l'autre SUM(X) + SUM(Y), l'utilisateur final obtiendra des résultats différents dès qu'une valeur nulle sera présente, ne serait-ce que le temps d'une minute. En revanche, si X et Y contiennent des nombres et rien d’autre, les deux formules sont bien équivalentes et les résultats égaux.

    On peut supposer que le détail des opérations que vous avez fourni vaut pour la norme SQL. Peut-être avez-vous une réponse à ce sujet, sinon peut-être SQLpro nous éclairera-t-il ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  4. #4
    J1
    J1 est déconnecté
    Membre expérimenté Avatar de J1
    Inscrit en
    Mai 2004
    Messages
    321
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 321
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Vous écrivez : "la fonction SUM ignore le NULL, qui ne se propage donc pas". Mais si l’on code :
    SELECT SUM (1 + Null)
    le résultat est quand même null...
    Le comportement que tu décris est justement en phase avec mon explication.
    En effet,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT SUM(1 + NULL)
    renvoie NULL car
    renvoie NULL.
    La requête équivaut donc à
    Or cette dernière requête renvoie bien NULL. Non pas parce que SUM tente de sommer NULL, mais au contraire parce que SUM exclut NULL de la somme et n'a donc rien à sommer. En conséquence, la fonction renvoie NULL pour indiquer que le résultat de cette somme est indéfini, car sans opérande.

    Citation Envoyé par fsmrel Voir le message
    On peut supposer que le détail des opérations que vous avez fourni vaut pour la norme SQL. Peut-être avez-vous une réponse à ce sujet, sinon peut-être SQLpro nous éclairera-t-il ?
    Trois cerveaux valent mieux que deux, je serais donc ravi d'avoir le point de vue de SQL Pro sur la question.


    Remarque : pour que la discussion ne soit pas trop complexe à prendre en route, je précise que la syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT SUM(1 + NULL)
    employée ici n'a bien sûr aucun lien avec la syntaxe SUM(valeur1,valeur2) que j'employais tout à l'heure pour symboliser le fonctionnement de la fonction SUM.

  5. #5
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 288
    Par défaut
    Je rejoins J1 sur tous les points. J'en profite pour préciser qu'Oracle et MySQL ont le même comportement.

    Quant au fait de ne pas utiliser NULL, ça me semble une erreur fondamentale. Le NULL a effectivement des propriétés contre-intuitives, mais souvent souhaitables.

  6. #6
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 213
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par Antoun
    Quant au fait de ne pas utiliser NULL, ça me semble une erreur fondamentale
    Une telle affirmation demande d'être étayée.

    Cela dit, je tiens à rappeler en passant, que lorsque l'on écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Create table T
    (
        X     Integer 
    )
    X est du type entier mais que NULL n'est pas un élément de l'ensemble des entiers (même si SQLpro fera la distinction entre NULL et marque nulle) : la mixture reste suspecte et conduit à des choses bizarres du genre du comportement de la fonction SUM, ou à un constat du genre :
    X < 0 ou X = 0 ou X > 0
    n'est pas une tautologie.

    Ne pas utiliser NULL est peut-être une erreur, mais utiliser NULL conduit vite à l'erreur. Un spécialiste de la chose sera d'une vigilance extrême, mais tout le monde n'est pas spécialiste. La logique ternaire nous entraîne vers des terrae incognitae, sur une pente fatale (comme dirait Fernand Naudin).
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

Discussions similaires

  1. [gridview]probleme de tri sur null
    Par anthyme dans le forum Windows Presentation Foundation
    Réponses: 2
    Dernier message: 05/08/2008, 16h29
  2. limiter un "-" dans un textbox et variations sur le thème ^^^
    Par petibonohm dans le forum Macros et VBA Excel
    Réponses: 75
    Dernier message: 29/02/2008, 15h17
  3. GROUP BY sur "NULL"
    Par alfredmobile dans le forum Langage SQL
    Réponses: 2
    Dernier message: 10/02/2008, 05h35
  4. Réponses: 11
    Dernier message: 03/05/2006, 15h12
  5. Pointeur sur NULL par défaut en parametre.
    Par KernelControl dans le forum Débuter
    Réponses: 3
    Dernier message: 15/12/2005, 10h09

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