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

Requêtes MySQL Discussion :

ORDER BY type FLOAT (et non type CHAR)


Sujet :

Requêtes MySQL

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    708
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 708
    Points : 133
    Points
    133
    Par défaut ORDER BY type FLOAT (et non type CHAR)
    Bonjour,

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT IF(longu='500', longt, longu) AS longu WHERE ... ORDER BY longu;

    longu est de type FLOAT
    longt est de type CHAR

    Le tri se fait comme si CHAR :

    1 m
    1,5 m
    10 m
    15 m
    2 m

    J'aimerais un tri comme FLOAT :

    1 m
    1,5 m
    2 m
    10 m
    15 m

    Bien sûr, je peux re-trier par PHP mais n'y a-t-il pas une solution par MySQL ?

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 410
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 410
    Points : 23 809
    Points
    23 809
    Par défaut
    Si le tri se fait par ordre alphabétique, comme pour une chaîne de caractères, c'est que tes valeurs doivent être déposées dans ta base sous forme de chaînes de caractères, et donc que les colonnes concernées portent le type CHAR ou VARCHAR. Ce serait ce point-là qu'il faudrait corriger en priorité si ce qu'elles contiennent est réellement des nombres. Il faudrait utiliser DECIMAL à la place.

    Pour une seule requête, tu peux toutefois te permettre de convertir ce contenu à la volée. Il y a plusieurs façons de le faire mais le plus simple ici, consiste à utiliser une sous-requête (ou une CTE avec « WITH » si le SGBD les reconnaît).

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      SELECT longueur FROM (SELECT CAST(IF(longu='500', longt, longu) AS DECIMAL(5,2)) AS longueur
                              FROM <ta table>
                             WHERE ... ) AS table_des_longueurs
    ORDER BY longueur

    Par contre, si tes chaînes utilisent des virgules « , » comme séparateurs décimaux et non des points « . » à l'anglo-saxonne, tu risques d'avoir des problèmes de collationnement.

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 394
    Points : 39 918
    Points
    39 918
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Citation Envoyé par boteha Voir le message
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT IF(longu='500', longt, longu) AS longu WHERE ... ORDER BY longu;

    longu est de type FLOAT
    longt est de type CHAR
    Effectivement, si le tri n'est pas celui souhaité, c'est que la colonne ciblée par la clause ORDER BY - donc la colonne "longu" - est de type CHAR ou VARCHAR
    De plus, si la colonne "longu" était d'un type numérique comme FLOAT, il ne faudrait pas encadrer la valeur 500 par des quotes, ce qui provoque un transtypage implicite, la bonne syntaxe serait :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT IF(longu=500, longt, longu) AS longu WHERE ... ORDER BY longu;

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    708
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 708
    Points : 133
    Points
    133
    Par défaut
    Bonjour,

    Merci de vos suivis.

    J'ai enlevé les apostrophes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT IF(longu=500, longt, longu) AS longu WHERE ... ORDER BY longu;
    Cela ne change rien au tri, hélas.

    Le champ longu est de type DOUBLE

    longt est de type varchar(200)

    Dans le champs longu DOUBLE le séparateur est un point, pas une virgule.

    J'ai besoin de comprendre la solution proposée par Obsidian, j'y reviens plus tard.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 857
    Points : 1 642
    Points
    1 642
    Par défaut
    Bonjour,
    partant de ce qui a été fourni
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT IF(longu='500', longt, longu) AS longu WHERE ... ORDER BY longu;
    longu est de type FLOAT
    longt est de type CHAR
    La question est : Quel est le type de la colonne longu resultante du SELECT ? (la colonne longu indiquée dans le IF provient d'une source inconnue mais dont on nous assure quelle est du type FLOAT)
    Vu qu'en cas de doute il est plus facile de transformer un FLOAT en CHAR que l'inverse => CHAR
    Du coup la projection sera du type CHAR

    On peut utiliser CAST pour imposer un type ; attention : il faut que ça marche ! vérifiez vos données

    Tant qu'on y est, ne pas nommer la colonne du même nom que l'une des 2 sources ^^
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT CAST(IF(longu=500, longt, longu) AS FLOAT ) AS long WHERE ... ORDER BY long;
    Le savoir est une nourriture qui exige des efforts.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    708
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 708
    Points : 133
    Points
    133
    Par défaut
    Bonjour Michel.Priori,

    Merci de ton suivi.

    Longu est de type DOUBLE.

    longt est de type VARCHAR.

    En ajoutant CAST dans la requête je récupère bien le bon ordre si toutes les valeurs de Longu sont différentes de 500.

    Par contre quand 500 appelle longt de type VARCHAR la chaîne que je récupère est tronquée et inutilisable.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 857
    Points : 1 642
    Points
    1 642
    Par défaut
    Citation Envoyé par boteha Voir le message
    longu est de type FLOAT
    longt est de type CHAR
    Citation Envoyé par boteha Voir le message
    Longu est de type DOUBLE.
    longt est de type VARCHAR.
    Ca change tout le temps ces trucs dis moi !
    Comment récupères tu le type de donnée ?

    Citation Envoyé par boteha Voir le message
    En ajoutant CAST dans la requête je récupère bien le bon ordre si toutes les valeurs de Longu sont différentes de 500.
    Par contre quand 500 appelle longt de type VARCHAR la chaîne que je récupère est tronquée et inutilisable.
    Ben vu d'ici, difficile d'apprécier ce qui est tronqué ou pas.

    Peux tu fournir des données sources et des données résultantes ?
    STP, des trucs qui peuvent être utilisé via db fiddle (https://www.db-fiddle.com/)

    et quels sont la version de Mysql et le mode SQL (https://dev.mysql.com/doc/refman/8.4/en/sql-mode.html) ?
    Le savoir est une nourriture qui exige des efforts.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    708
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 708
    Points : 133
    Points
    133
    Par défaut
    Bonjour,

    Merci de votre suivi.

    Je vais essayer quelque chose de simple :

    SELECT longu, longt WHERE ... ORDER BY longu, longt;

    Dans la réalité :
    Soit tous les longu valent 500, les longt sont des STRING, j'espère un tri alphabétique des strings.
    Soit tous les longu ont une valeur numérique différente de 500, les longt sont NULL, j'espère un tri numérique des DOUBLE.

    L'ennui est que je récupère deux champs dans PHP, ce qui m'oblique à un code plus compliqué que si un seul champ.

    Je vous tiens informés.

  9. #9
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 394
    Points : 39 918
    Points
    39 918
    Billets dans le blog
    9
    Par défaut
    Pouvez-vous communiquer le script DDL de création de la table (ordre complet CREATE TABLE) : show create table ma_table

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    708
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 708
    Points : 133
    Points
    133
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Pouvez-vous communiquer le script DDL de création de la table (ordre complet CREATE TABLE) : show create table ma_table
    Merci de ton suivi mais ne te casse pas la tête.

    Le problème a été contourné plus que résolu mais le contour me plait et je coche Résolu.

    Encore merci de votre suivi.

  11. #11
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 394
    Points : 39 918
    Points
    39 918
    Billets dans le blog
    9
    Par défaut
    C'est dommage de ne pas fournir d'une part le DDL comme demandé et d'autre part la solution de contournement, car les autres participants du forum sont également intéressés par la solution.
    Et c'est le principe d'un forum que de partager les connaissances et les expériences

  12. #12
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 609
    Points : 19 833
    Points
    19 833
    Par défaut
    Salut à tous.

    Sans savoir de quoi il en retourne, c'est un problème de modélisation des tables.
    Pourquoi utilisez les types float ou double qui sont réservés au calcul scientifique ?
    Si vous utilisez du numérique, autant utiliser le bon type : decimal.
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    708
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 708
    Points : 133
    Points
    133
    Par défaut
    Bonjour,

    Merci de votre suivi.

    Citation Envoyé par escartefigue Voir le message
    C'est dommage de ne pas fournir d'une part le DDL comme demandé et d'autre part la solution de contournement, car les autres participants du forum sont également intéressés par la solution.
    Et c'est le principe d'un forum que de partager les connaissances et les expériences
    J'ai donné la solution de contournement :

    Citation Envoyé par boteha
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT longu, longt WHERE ... ORDER BY longu, longt;
    Dans la réalité :
    Soit tous les longu valent 500, les longt sont des STRING, j'obtiens un tri alphabétique des strings.
    Soit tous les longu ont une valeur numérique différente de 500, les longt sont NULL, j'obtiens un tri numérique des DOUBLE.
    Il me semble avoir aussi donné la DDL, si on parle de la même chose.

    longu = VARCHAR
    longt = DOUBLE

    Citation Envoyé par Artemus24
    Sans savoir de quoi il en retourne, c'est un problème de modélisation des tables.
    Pourquoi utilisez les types float ou double qui sont réservés au calcul scientifique ?
    Si vous utilisez du numérique, autant utiliser le bon type : decimal.
    J'ai besoin d'un nombre relatif avec un gros paquet de décimales possible.

    J'avoue ne pas connaître l'intérêt de DECIMAL par rapport à DOUBLE, ni bien comprendre à la lecture de la doc SQL.

    Mais mon problème concerne le tri, uniquement le tri.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT IF(longu='500', longt, longu) AS longu WHERE ... ORDER BY longu;
    Avec cette requête le tri est alphabétique.
    En quoi DECIMAL au lieu de DOUBLE changerait quelque chose ?

  14. #14
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 609
    Points : 19 833
    Points
    19 833
    Par défaut
    Citation Envoyé par Boteha
    J'avoue ne pas connaître l'intérêt de DECIMAL par rapport à DOUBLE, ni bien comprendre à la lecture de la doc SQL.
    L'intérêt est dans la précision du calcul.

    Citation Envoyé par Boteha
    En quoi DECIMAL au lieu de DOUBLE changerait quelque chose ?
    Si vous avez besoin de trier des nombres, autant les mettre dans un type qui permet d'obtenir ce que vous cherchez à faire.
    A vrai dire, on ne sait rien de ce que vous essayez de faire.
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  15. #15
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    708
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 708
    Points : 133
    Points
    133
    Par défaut
    Bonjour Artemus24,

    Merci de ton suivi.

    Mes champs sont bien typés il me semble :

    DOUBLE pour tri numérique.
    VARCHAR pour tri alphabétique.

    DOUBLE ne sert pas au calcul.
    C'est un code qui est décodé dans PHP pour générer une STRING plus ou moins complexe.
    Et cela sert aussi au tri.

    Grâce à vous j'ai trouvé une solution de contournement efficace, encore merci.

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

Discussions similaires

  1. [Python 3.X] Swinnen 13.18 can't multiply sequence by non-int of type 'float'
    Par loncle dans le forum Général Python
    Réponses: 3
    Dernier message: 08/07/2015, 22h58
  2. Réponses: 4
    Dernier message: 01/07/2005, 17h20
  3. Pb de formatage de champs de type float
    Par FrankyNormand dans le forum XMLRAD
    Réponses: 9
    Dernier message: 05/05/2005, 13h37
  4. Combinaisons de type signés et non signés
    Par Hell dans le forum Langage
    Réponses: 4
    Dernier message: 01/11/2004, 20h01
  5. [MS-SQL][ADO] précision du type FLOAT
    Par Le Lézard dans le forum Bases de données
    Réponses: 2
    Dernier message: 23/09/2004, 16h30

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