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

MySQL Discussion :

Requete la valeur juste ou la plus proche


Sujet :

MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Par défaut Requete la valeur juste ou la plus proche
    Salut à tous,

    J'aimerai savoir si il est possible de faire en une seule requete, la selection suivante :

    J'aimerai retrouver dans une un champ (numérique) d'une de mes tables un valeur bien précise ou bien si elle n'existe pas la valeur la plus proche (plus haute ou plus basse).

    Exemple :

    MATABLE.ID /// MATABLE.NUMERO
    1 /// 100
    2 /// 110
    3 /// 120
    4 /// 130
    5 /// 140

    Si je passe mon paramètre 120, je récupère 3
    Si je passe mon paramètre 129, je récupère 4
    Si je passe mon paramètre 125, je récupère 3 ou/et 4 (pas d'importance)

    D'avance merci de votre aide.


  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    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 : 22 010
    Billets dans le blog
    6
    Par défaut
    Avec le jeu d'essais suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE T_JALON_JLN
    (JLN_ID     INT,
     JLN_VALUE  INT)
     
    INSERT INTO T_JALON_JLN VALUES (1, 110)
    INSERT INTO T_JALON_JLN VALUES (2, 120)
    INSERT INTO T_JALON_JLN VALUES (3, 130)
    INSERT INTO T_JALON_JLN VALUES (4, 140)
    INSERT INTO T_JALON_JLN VALUES (5, 150)
    MERCI A L'avenir de donner vos table sous forme DDL et un jeu d'essais sous forme INSERT !


    Voici la requête :

    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
    SELECT VAL
    FROM   (SELECT MAX(T1.JLN_VALUE) AS VAL, 125 - MAX(T1.JLN_VALUE) AS ECART
            FROM   T_JALON_JLN AS T1
            WHERE  T1.JLN_VALUE < 125
            UNION ALL
            SELECT MIN(T1.JLN_VALUE) AS VAL, MIN(T1.JLN_VALUE) - 125 AS ECART
            FROM   T_JALON_JLN AS T1
            WHERE  T1.JLN_VALUE >= 125) AS TT
    WHERE ECART = (SELECT MIN(ECART) 
                   FROM   (SELECT MAX(T1.JLN_VALUE) AS VAL, 125 - MAX(T1.JLN_VALUE) AS ECART
                           FROM   T_JALON_JLN AS T1
                           WHERE  T1.JLN_VALUE < 125
                           UNION ALL
                           SELECT MIN(T1.JLN_VALUE) AS VAL, MIN(T1.JLN_VALUE) - 125 AS ECART
                           FROM   T_JALON_JLN AS T1
                           WHERE  T1.JLN_VALUE >= 125) AS T)
    Dans cet exemple la valeur recherchée est 125...

    Cette requête serait plus élégante, concise, rapide et lisible si elle pouvait bénéficier de la technique des CTE hélas inconnue de MySQL (le niveau de langage SQL de MySQL étant encore à peine celui de la norme de 1992 !). Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    WITH 
    T AS (SELECT MAX(T1.JLN_VALUE) AS VAL, 125 - MAX(T1.JLN_VALUE) AS ECART
          FROM   T_JALON_JLN AS T1
          WHERE  T1.JLN_VALUE < 125
          UNION ALL
          SELECT MIN(T1.JLN_VALUE) AS VAL, MIN(T1.JLN_VALUE) - 125 AS ECART
          FROM   T_JALON_JLN AS T1
          WHERE  T1.JLN_VALUE >= 125)
    SELECT VAL
    FROM   T
    WHERE  ECART = (SELECT MIN(ECART)
                    FROM   T)
    A lire sur le sujet : http://sqlpro.developpez.com/cours/s...te-recursives/

    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/ * * * * *

  3. #3
    Futur Membre du Club
    Inscrit en
    Décembre 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 5
    Par défaut
    ça paraît vachement compliqué SQLpro...
    pourquoi pas simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select MATABLE.ID, ABS(MATABLE.NUMERO - 100) AS val
    from MATABLE
    order by val ASC 
    LIMIT 1

  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
    22 010
    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 : 22 010
    Billets dans le blog
    6
    Par défaut
    Parce que c'est totalement faux !
    Des opérateurs comme LIMIT ou TOP sont totalement aberrants car ne respecte pas le côté ensembliste des requêtes SQL et conduit à des résultats faux.

    Par exemple dans l'exemple que j'ai donné, la valeur 125 ne produit pas un seul résultat mais 2. En effet 125 est exactement au milieu de l'intervalle et il n'y a aucune raison pour privilégier arbitrairement une valeur plutôt qu'une autre comme le fait obligatoirement ces opérateurs anti relationnels que sont LIMIT ou TOP !

    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/ * * * * *

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

Discussions similaires

  1. [Toutes versions] Cellule colorée si valeur parmi d'autre plus proche de 20
    Par 8e8eClo dans le forum Excel
    Réponses: 1
    Dernier message: 09/02/2011, 11h02
  2. Valeur Egale ou la plus proche
    Par tripper.dim dans le forum MySQL
    Réponses: 1
    Dernier message: 20/12/2008, 11h38
  3. Comparaison d'une valeur pour trouver la plus proche
    Par Falcdyr dans le forum VBA Access
    Réponses: 4
    Dernier message: 16/04/2008, 17h10
  4. [Oracle] selectionner la valeur la plus proche
    Par jaoued dans le forum Langage SQL
    Réponses: 5
    Dernier message: 08/03/2006, 21h15
  5. Récupurer via une requête SQL la valeur la plus proche
    Par yoda_style dans le forum Langage SQL
    Réponses: 9
    Dernier message: 27/04/2004, 13h52

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