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 :

GROUP BY & ORDER BY & MAX [MySQL-5.7]


Sujet :

Requêtes MySQL

  1. #1
    Membre régulier
    Homme Profil pro
    Symfony - CMS Wordpress - Zend
    Inscrit en
    Septembre 2011
    Messages
    306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Symfony - CMS Wordpress - Zend
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2011
    Messages : 306
    Points : 101
    Points
    101
    Par défaut GROUP BY & ORDER BY & MAX
    Bonjour,

    Je travail avec MYSQL,

    J'ai une liste qui ne se trie pas correctement,

    Je voudrait avoir un trie correct par ordre Alphabétique

    dans la requete je remarque ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORDER BY MAX(timestamp)
    Ma requête est faite en Java en backend et envoyé dans front (Angular2)

    La requête est assez complexe je vous explique les grande ligne:
    Je recupere au fur et mesure mes entrés
    certaines sont plus courte que d'autre je n'ai pas de pattren spécifique
    quand je demande le trie sur "tmp.refference_num" il me trie pas correctement..
    Voici la structure du sql sur le projet sur le travail
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT ...
    FROM (SELECT ... FROM ... JOIN ... JOIN ... ...
          WHERE 1 AND ...
          GROUP BY ...
          HAVING MAX(...) IS NULL
          OR MAX(...) IS FALSE
          ORDER BY NULL) AS tmp JOIN ... JOIN ... ..
    WHERE 1
    GROUP BY ...
    ORDER BY MIN(...) ASC, MAX (...) ASC, ... DESC, MAX(tmp.refference_num) DESC , NULL
    Voici ma question:
    • Qu'est-ce que est censé faire MAX dans ma requête dans le dernier ORDER BY?
    • Dans le select imbriquer quel "order by" prime sur lequel?
    • Il y a pas moyen d'optimiser tous ça?


    Je sais je donne pas beaucoup d'infos mais cela compliquerais encore plus avec les nomenclature sur lequelle je travail

    Merci pour vos réactions.

    EDIT:
    Voici mes resultat:

    T000206
    T00099
    T00098
    T00097
    ...
    T000205

    J'ai essayé ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ORDER BY RIGHT(tmp.refference_num,5) DESC
    Mais quand mes refférences son plus courte que les autres ça fausse le trie.. Non?
    Quel la meilleur façon de comparer des refferences clients? je suis sous Java compareTo me parait plus efficace?
    La je recupere rien de ma db sous Java..
    Tous ce fait avec un requête Mysql
    Qu'en pensé vous?

  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
    21 768
    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 : 21 768
    Points : 52 577
    Points
    52 577
    Billets dans le blog
    5
    Par défaut
    Votre requête comporte beaucoup de choses incohérente...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT ...
    FROM (SELECT ... FROM ... JOIN ... JOIN ... ...
          WHERE 1 AND ...
          GROUP BY ...
          HAVING MAX(...) IS NULL
          OR MAX(...) IS FALSE
          ORDER BY NULL) AS tmp JOIN ... JOIN ... ..
    WHERE 1
    GROUP BY ...
    • Un ORDER BY dans une sous requête est interdit. Mais MySQL étant l'un des SGBDR les plus mauvais, il vous laisse faire n'importe quoi. Cela n'a aucun sens (au propre comme au figuré) de mettre un ordre à une étape de résultats intermédiaire. De plus un ORDER BY NULL est hautement stupide car faire un tri sur une constante revient à ne rien faire (en principe car MySQL est assez con pour faire quand même le tri !).
    • WHERE 1 dans la sous requête, comme dans la requête principale, n'est pas cohérent. 1 n'est pas un prédicat... Les expressions dans le WHERE doivent être des prédicats (c'est a dire évauable à Vari ou faux.... Or 1 n'est ni vrai ni faux !


    Il y en a probablement d'autre, mais il faut poster la requête entière.

    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
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 053
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 053
    Points : 9 392
    Points
    9 392
    Par défaut
    On va simplifier la question.
    Tu demandes à quoi correspond un order by max() dans une requête.
    Imaginons une base de données vec des clients et des commandes. Et pour chaque client, on veut afficher le montant de la commande la plus élevée qu'il a faite. On va faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Select idClient,max(montant) from commandes 
    group by idClient
    Et si on veut que les lignes soient affichées selon la colonne 2 (en première ligne, le client qui a passé la plus grosse commande)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Select idClient,max(montant) from commandes 
    group by idClient
    order by max(montant) desc
    Ca , c'est pour la première question.
    Ensuite, tu dis que tu veux un tri sur le n° de référence. Et tes n°s de référence sont de la forme
    T000205
    T00099
    T00098

    J'imagine que tu veux obtenir cet ordre :
    T00098
    T00099
    T000205

    Il faut donc 'supprimer le 1er caractère', j'imagine que ce 1er caractère est non-significatif, c'est toujours la lettre T
    Puis convertir les caractères restants en nombre. Et en cherchant quelques secondes, on trouve :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    order by  cast  (  substr( tmp.refference_num,2,6) as SIGNED )
    PS : Si tu as des difficultés avec ce tri, c'est tout simplement parce que ta base de données est mal conçue. On ne met pas un identifiant sous la forme lettres+chiffres. Ou alors, on fait en sorte que la longueur de la chaine obtenue soit constante, en dimensionnant correctement la colonne.
    Si au moins les nombres au delà de 100 étaient écrits T00205 au lieu de T000205, tu n'aurais pas de problème !

    Mais T000 suivi du nombre, c'est du vice.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  4. #4
    Membre régulier
    Homme Profil pro
    Symfony - CMS Wordpress - Zend
    Inscrit en
    Septembre 2011
    Messages
    306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Symfony - CMS Wordpress - Zend
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2011
    Messages : 306
    Points : 101
    Points
    101
    Par défaut Requête complète..
    Bonsoir,

    Merci pour vos réactions..

    Désole TBC92,

    Je ne donnais que un exemple,

    je suis rester très vague sans rentrer dans les détails..

    La chaine devrais être très aléatoire pas de répétition etc..

    Je répète encore je veux simplement réécrire complètement cette requête car je trouve comme la dit Frédéric:

    Votre requête comporte beaucoup de choses incohérente...
    Je suis la demande de Frédéric, voici la requête complè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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    SELECT tmp.customer_group_id AS id
    FROM
      (SELECT customer_group_id,
              customer_group_order,
              customer_id,
              customer_visualized,
              customer_group_is_active,
              customer_group_banned,
              customer_group_action_actived,
              customer_status_fk,
              file_settings.id AS file_settings_id,
              customer_group_from_customer_true AS from_customer_true,
              customer_order_fk
       FROM customer_group
       JOIN customer ON customer_group_fk = customer_group_id
       JOIN customer_file_entry ON customer_file_entry_customer_fk = customer_id
       JOIN file_entry ON customer_file_entry_file_entry_fk = file_entry_id
       JOIN FILE ON file_id = file_entry_file_fk
       JOIN file_settings ON file_settings.id = file_settings_fk
       LEFT JOIN file_role_allowed ON file_entry_file_fk = file_role_allowed.file_fk
       WHERE 1
         AND customer_group_is_expired IS FALSE
         AND customer_type_fk = :customerType
         AND customer_status_fk IN (:customerstatusFKs)
       GROUP BY customer_group_id,
                customer_group_order,
                customer_group_is_active,
                customer_id,
                customer_visualized,
                customer_status_fk,
                customer_group_from_customer_true,
                customer_group_banned,
                customer_group_action_actived,
                file_settings_id,
                customer_order_fk
       HAVING MAX(file_role_allowed.file_fk) IS NULL
       OR MAX(:role_1 = file_role_allowed.role_role) IS FALSE
       ORDER BY NULL) AS tmp
    JOIN order_customer ON tmp.customer_order_fk = order_id
    JOIN file_settings ON tmp.file_settings_id = file_settings.id
    LEFT JOIN bm ON tmp.customer_id = bm_customer_fk
    LEFT JOIN customer_received_order ON tmp.customer_id = customer_received_order_customer_fk
    LEFT JOIN share_order_preferences ON customer_received_order_received_order_fk = share_order_preferences.id
    WHERE 1
    GROUP BY tmp.customer_group_id,
             tmp.customer_group_is_active,
             tmp.customer_group_banned,
             tmp.from_customer_enabled,
             tmp.customer_group_action_actived,
             tmp.customer_group_order
    ORDER BY MIN(color_fk) ASC, MAX(priority) ASC, tmp.customer_group_is_active DESC,
                                                   MAX(order_datetime) DESC, NULL
    Merci.

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    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 : 21 768
    Points : 52 577
    Points
    52 577
    Billets dans le blog
    5
    Par défaut
    déjà vous pouvez simplifier la requête comme suit :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    SELECT tmp.customer_group_id AS id
    FROM
      (SELECT customer_group_id
       FROM customer_group
       JOIN customer ON customer_group_fk = customer_group_id
       JOIN customer_file_entry ON customer_file_entry_customer_fk = customer_id
       JOIN file_entry ON customer_file_entry_file_entry_fk = file_entry_id
       JOIN FILE ON file_id = file_entry_file_fk
       JOIN file_settings ON file_settings.id = file_settings_fk
       LEFT JOIN file_role_allowed ON file_entry_file_fk = file_role_allowed.file_fk
       WHERE customer_group_is_expired IS FALSE
         AND customer_type_fk = :customerType
         AND customer_status_fk = :customerstatusFKs
       GROUP BY customer_group_id
       HAVING MAX(file_role_allowed.file_fk) IS NULL
       OR MAX(:role_1 = file_role_allowed.role_role) IS FALSE) AS tmp
    JOIN order_customer ON tmp.customer_order_fk = order_id
    JOIN file_settings ON tmp.file_settings_id = file_settings.id
    LEFT JOIN bm ON tmp.customer_id = bm_customer_fk
    LEFT JOIN customer_received_order ON tmp.customer_id = customer_received_order_customer_fk
    LEFT JOIN share_order_preferences ON customer_received_order_received_order_fk = share_order_preferences.id
    GROUP BY tmp.customer_group_id,
             tmp.customer_group_is_active,
    ORDER BY MIN(color_fk) ASC, MAX(priority) ASC, tmp.customer_group_is_active DESC,
                                                   MAX(order_datetime) DESC
    Ensuite comme vous n'avez pas respecté la première forme normale:
    Tout attribut d'une relation doit être atomique
    Et que votre colonne refference_num (que je ne voit d'ailleurs pas dans votre requête...) contient :
    • T000205
    • T00099
    • T00098

    donc plusieurs informations, dont une sur laquelle vous voulez trier et qu'en plus les différentes parties ne sont pas du même type, et que l'on a fait un bouliboulga... Il faudra tout simplement le découper pour pouvoir l'ordonner. Le mieux étant de créer une UDF particulière pour extraire juste cette information et intégrer cette UDF à la requête.

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

  6. #6
    Membre régulier
    Homme Profil pro
    Symfony - CMS Wordpress - Zend
    Inscrit en
    Septembre 2011
    Messages
    306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Symfony - CMS Wordpress - Zend
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2011
    Messages : 306
    Points : 101
    Points
    101
    Par défaut Réaction au sujet de la requête
    Merci pour ton message.

    Dans le resultas de la sous requête je doit accéder a une colonne
    Ce que dans ta solution je ne peux pas faire

    Où est-ce je peux accéder a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tmp.customer_group_is_active,
    ?

    Je voudrait avoir les resultats sur cette table:

    Nom : Untitled.png
Affichages : 717
Taille : 40,0 Ko

    L'UDF vas servir à optimiser la requête ou pour un autre usage?

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    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 : 21 768
    Points : 52 577
    Points
    52 577
    Billets dans le blog
    5
    Par défaut
    Je vous ais mis -1 par ce que vous nous postez une requête qui n'est visiblement pas celle que vous nous demandez de travailler....

    Dans votre requête du post : https://www.developpez.net/forums/d1...x/#post9638012
    Que vous qualifiez de requête complète...

    Dans votre post https://www.developpez.net/forums/d1...x/#post9641987 vous nous dites maintenant qu'il faut avoir dans le résultat les colonnes tmp.customer_group_is_active et d'autres encore...

    J'ai donc l'impression d'avoir été pris pour un con et d'avoir travaillé pour vous inutilement !

    Commencez donc par être cohérent et intelligent, ça va nous simplifier la vie !
    En attendant moi je renonce, je n'ai pas de temps à perdre...

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

  8. #8
    Membre régulier
    Homme Profil pro
    Symfony - CMS Wordpress - Zend
    Inscrit en
    Septembre 2011
    Messages
    306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Symfony - CMS Wordpress - Zend
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2011
    Messages : 306
    Points : 101
    Points
    101
    Par défaut Je comprends votre mécontentement.. Mais
    Je suis désolée pour ne pas avoir posté la requête.

    Quand bien même, je n'aurais pas pu le faire sans modifier le contexte.

    Pour les reste l'ordre de trie importe peux, car les changements à faire sont minime.

    Mon objectif était de comprendre l'ordre de la requête et le retour de celle-ci.

    Je suis d'accord que vous répondez et écrivez a beaucoup de poste, et que cela peut vous offusquer.

    J'aurais plutôt pris cela positivement pas comme votre réaction un peu exagéré..

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

Discussions similaires

  1. Combinaison de Group By et max
    Par santana2006 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 07/04/2008, 00h56
  2. Somme Group by et Max date
    Par mamiberkof dans le forum Langage SQL
    Réponses: 5
    Dernier message: 03/04/2008, 16h48
  3. access 2003 group by et max
    Par Bba_M dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 29/01/2008, 15h00
  4. pb GROUP BY et max()
    Par wac9258 dans le forum Requêtes
    Réponses: 1
    Dernier message: 27/03/2007, 19h56
  5. [SQL2005] group by et max(date)
    Par BOUBOU81 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 11/12/2006, 16h54

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