Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

j'ai deux tables en relations colis(id,agence_id,frais,numero_facture,code_colis, nature,created,modified,etat) et la table agence(id,nom_agence,date_crea) contenant ceci:

TABLE COLIS
id agence_id frais numero_facture code_colis nature created modified etat
1 1 2500 1 PR001 SAC 2017-11-06 18:19:21 2017-11-06 18:19:21 1
2 2 500 1 PR001 SAC2 2017-11-06 18:19:24 2017-11-06 18:19:24 1
3 1 250 1 PR001 SAC3 2017-11-06 18:19:30 2017-11-06 18:19:30 1
4 1 2300 2 PR002 SACE 2017-11-06 18:19:45 2017-11-06 18:19:45 1
6 1 500 2 PR002 SAC DS 2017-11-06 18:19:50 2017-11-06 18:19:50 1
7 1 2500 3 PR001 SAC 2017-11-06 18:19:21 2017-11-06 18:19:21 1

TABLE AGENCE

id nom_agence etat
1 AFRIK 1
2 SALOM 1

Entourez votre code pour bien le mettre en forme

Ce que je veux

Je veux récupérer tous les plus colis qui ont la plus petite valeur par groupe de numero de facture
voici ce que je fais:

SELECT MIN(frais), code_colis,nature,nom_agence,,colis.created FROM colis,agences WHERE colis.agence_id = agences.id AND etat >= 1 GROUP by numero_facture

Ce que j'obtiens

Error: SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mybd.Colis.frais' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

7 réponses


Bonjour romses

dans ton SELECT tu ne peux mettre que des champs qui servent au regroupement (après GROUP BY)
ou alors ils doivent apparaitre dans une opération (Min, Max, Sum ...)
En gros tu peux faire

SELECT numero_facture, MIN(frais) FROM colis,agences WHERE colis.agence_id = agences.id AND etat >= 1 GROUP by numero_facture

D'autre part la norme pour les jointures est maintenant d'utiliser JOIN

SELECT numero_facture, MIN(frais) FROM colis INNER JOIN agences ON colis.agence_id = agences.id WHERE etat >= 1 GROUP BY numero_facture

Salut;
Il faut annuler la paramètre sql_mode de mysql.

voila comment je fais.

    try {
        $connexion = new PDO('mysql:host='.$host.';dbname='.$database, $userdb, $passdb);
        $connexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $sqlx = <<<EOM
            SET GLOBAL sql_mode = '';
            SET SQL_SAFE_UPDATES = 0;
EOM;

        $connexion->query($sqlx);
        $connexion->query("SET NAMES utf8;");
        $connexion->query("SET lc_time_names = 'fr_FR';");

        //$connexion->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true);
        $msgerr = '';
    } catch (Exception $exc) {
        $msgerr = $exc;
        // echo "Erreur : $msgerr !!!!!!!!!!!!!!!!!!!!!";

    }

après, tu peux faire ta requète avec un groupe by non nommé dans le select.

@plus

Pierre

romses
Auteur

Merci déjà @Huggy et pierrot mais huggy si je veux alors avoir les résultats avec tous les nom des agences et certains champs dans la table colis je fais comment? car ta requête fonctionne sauf que je n'ai pas la possibilité de retourné plus de champs

@romses , avec la méthode que je t'ai donné, ta requète fonctionne.
@plus

Pierre

Tout dépend des champs que tu veux rapatrier, s'ils sont propre à une facture alors tu les rajoute dans le regroupement, cela ne modifiera pas la façon de regrouper
Par contre si tu souhaites avoir des données du colis (le Min) il faut refaire une jointure avec la table Colis

SELECT * FROM Colis INNER JOIN (SELECT numero_facture, MIN(frais) AS minifrais FROM colis INNER JOIN agences ON colis.agence_id = agences.id WHERE etat >= 1 GROUP BY numero_facture) AS R2 ON (Colis.frais = R2.miniFrais AND Colis.numero_facture = R2.numero_facture)

@Pierrot01 si tu rajoutes dans le SELECT des champs qui ne font pas partie du GROUP BY, alors il est impossible de dire à quelle ligne ils appartiennent
si par exemple tu fais

SELECT numero_facture, MIN(frais), MAX(frais),  code_colis FROM colis INNER JOIN agences ON colis.agence_id = agences.id WHERE etat >= 1 GROUP BY numero_facture

le code_colis est celui du Max ou celui du Min ou bien le premier code_colis qu'il a trouvé ? impossible à dire
c'est pour ça que c'est une erreur SQL (tous les SGBD)

Voir la doc MySQL ici
et notamment la phrase " The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate."

romses
Auteur

Merci @Huggy pour ta requête elle fonctionne bien sauf une préocupation si après avoir fait un group by on a deux élément qui ont même valeur comment prendre un parmis les deux? je veux dire j'ai deux colis ayant le même numereau de facture et le même montant de frais comment prendre un montant et laisser l'autre?