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 :

Ne retourner que la "meilleure" valeur pour chaque jour


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 13
    Points
    13
    Par défaut Ne retourner que la "meilleure" valeur pour chaque jour
    Bonjour,

    J'aimerai obtenir de l'aide sur une requete SQL. Le probleme me parait simple et pourtant...

    La table (simplifiée) est construite comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Date             Type           Valeur
    01/01/2000      1                    5
    01/01/2000      3                 4.5     -- type 1 sera préféré
    02/01/2000      3                    6
    03/01/2000      2                    8    -- type 2 sera préféré
    03/01/2000      3                    7
    04/01/2000      3                    9
    Je souhaite retourner ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Date             Type           Valeur
    01/01/2000      1                    5
    02/01/2000      3                    6
    03/01/2000      2                    8
    04/01/2000      3                    9
    Je n'arrive pas a faire cela avec une simple requete SQL.

    Si c'est possible alors j'aimerai rajouter 2 difficultés
    - J'aimerai pouvoir spécifier l'ordre d'importance de la colonne Type (ex: 1,2,3 ou 2,1,3 ou 3,1,2, etc).
    - La solution doit etre tres rapide (Base de 500 GO avec des tables de plusieurs centaines de millions d'enregistrements et chaque requete renvoie entre 20'000 a 500'000 valeurs, le nombre de requetes par seconde peut être tres élevé).

    Jusqu'a present nous faisons cela au niveau des applications. Afin de réduire la charge réseau on souhaiterait le faire au niveau de SQL server.

    Avez-vous la moindre piste pour faire cela en SQL ? Doit-on passer par une fonction C# dans SQL Server ?

    Qu'en pensez-vous ?

    Merci,
    Michael M.

  2. #2
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 13
    Points
    13
    Par défaut Une premiere solution avec UNION
    Apres une longue reflexion, j'ai une premiere solution que je vous soumets:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT DATE, Type, Valeur
    FROM table_X
    WHERE Type=1
    UNION
    SELECT DATE, Type, Valeur
    FROM table_X
    WHERE Type=2 AND Date NOT IN (SELECT DATE from table_X WHERE Type=1)
    UNION
    SELECT DATE, Type, Valeur
    FROM table_X
    WHERE Type=3 AND Date NOT IN (SELECT DATE from table_X WHERE Type IN (1,2))
    Dans nos conditions d'utilisation cela demande d'ecrire la requete a la volee.
    Problemes supplementaires : on a environ 15 valeur de Type differentes.

    Et aussi il nous est necessaire de faire des aggregations avec des "Group BY".

    Bon, continuons de reflechir.

    Avez-vous plus simple peut etre?

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Utilisez une fonction analytique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT
        SR.Date, SR.Type, SR.Valeur
    FROM
        (SELECT
            Date, Type, Valeur,
            rank() over(PARTITION by Date order by Valeur desc) rk
        FROM table_X) as SR
    WHERE
        SR.rk = 1
    Vous n'avez pas précisé comment gérer les égalités.
    Vous pouvez utiliser dense_rank() si rank() ne convient pas.

  4. #4
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Vous pouvez utiliser dense_rank() si rank() ne convient pas.
    Merci,

    J'avais regarde la fonction rank() mais la difficulte est que l'ordre prefere du type n'est pas forcement 1,2,3 ou 3,2,1. Cela peut etre 1,3 ou 2,1 ou 3,1 ou 3,1,2 ou 2,3,1... Et j'ai en tout une quinzaine de valeurs de Type dont l'ordre d'importance peut etre n'importe quelle combinaison.

    En reflechissant un peu plus peut etre dois-je passer par une table temporaire pour specifier l'ordre de priorite que la clause ORDER BY de la fonction rank doit utiliser ?

    mmmm C'est une piste.

    Une autre facon de faire est de passer par une fonction qui renvoie une table.

    Merci,
    Michael M.

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Ah j'ai mal compris, je pensais que vous préfériez le type qui avait la plus forte valeur.

    Comment choisissez-vous votre type ?

  6. #6
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Comment choisissez-vous votre type ?
    L'utilisateur peut choisir la hierarchie des types de facon completement arbitraire. A ce jour on a environ 30 hierarchies differentes et de nouvelles sont rajoutees assez regulierement.

    Si dans les fonctions SQL on pouvait faire du SQL dynamique mon probleme serait resolu. Peut etre dois-je passer par une fonction ecrite en C#... Ca m'ennuie assez car cela n'est pas portable du tout.

    Merci.

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    C'est pour celà qu'il existe des outils comme BO, SSRS, Cognos et cetera.
    Le SQL n'est effectivement pas très dynamique de nature.

Discussions similaires

  1. Réponses: 1
    Dernier message: 26/06/2007, 12h26
  2. Réponses: 1
    Dernier message: 12/03/2007, 14h53

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