2017-10-13 32 views
0

J'ai le tableau suivant dans mysql qui est une version réduite d'un vrai problème.Comment conserver une colonne supplémentaire après l'agrégation?

+-------+-------+-------+-------+ 
| a_col | b_col | c_col | extra | 
+-------+-------+-------+-------+ 
|  1 |  1 |  1 |  7 |* 
|  1 |  2 |  1 | 10 | 
|  1 |  2 |  2 | 20 |* 
|  1 |  3 |  2 | 20 | 
|  1 |  3 |  3 | 15 |* 
+-------+-------+-------+-------+ 

Je veux sélectionner les lignes marquées *, pour obtenir le tableau suivant:

+-------+-------+-------+-------+ 
| a_col | b_col | c_col | extra | 
+-------+-------+-------+-------+ 
|  1 |  1 |  1 |  7 | 
|  1 |  2 |  2 | 20 | 
|  1 |  3 |  3 | 15 | 
+-------+-------+-------+-------+ 

Si deux lignes ont la même valeur dans a_col ET b_col, puis garder celui qui a le plus grand valeur dans le c_col

Ma tentative a été:

select a_col, b_col, max(c_col), extra 
from mytable 
group by a_col, b_col 

Mais je reçois le message d'erreur suivant :

ERROR 1055 (42000): Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'bd17_g12.mytable.extra' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 

sans mentionner la colonne « extra » je reçois quelque chose à ce que je veux:

+-------+-------+------------+ 
| a_col | b_col | max(c_col) | 
+-------+-------+------------+ 
|  1 |  1 |   1 | 
|  1 |  2 |   2 | 
|  1 |  3 |   3 | 
+-------+-------+------------+ 

Mais je dois garder les valeurs de la colonne « extra »

Répondre

0

Vous pouvez obtenir la colonne extra et c_col en appliquant la fonction agrégée group_concat. Et pour choisir la plus haute c_col liée et sa connexes valeur supplémentaire que vous pouvez utiliser substring_index dessus

select a_col, b_col, max(c_col), 
substring_index(group_concat(extra order by c_col desc),',',1) `extra` 
from mytable 
group by a_col, b_col 

DEMO

Ou avec moi rejoindre

select a.* 
from mytable a 
left join mytable b 
      on a.a_col = b.a_col 
      and a.b_col = b.b_col 
      and a.c_col < b.c_col 
where b.c_col is null 

DEMO

0

Si je comprends bien, vous voulez le extra pour le plus grand c_col.

SQL Fiddle

MySQL 5.6 Configuration du schéma:

Requête 1:

select t2.* 
from (
    select a_col, b_col, max(c_col) c_colm 
    from t 
    group by a_col, b_col 
) t1 
    INNER join t t2 
    on t1.a_col = t2.a_col 
     and t1.b_col = t2.b_col 
     and t1.c_colm = t2.c_col 

Results:

| a_col | b_col | c_col | extra | 
|-------|-------|-------|-------| 
|  1 |  1 |  1 |  7 | 
|  1 |  2 |  2 | 20 | 
|  1 |  3 |  3 | 15 | 
0

L'erreur que vous obtenez lorsque vous incluez la colonne extra ne semble pas se produire pour une version faible de mysql (telle que la version 5.5). Donc, le problème pourrait être avec le problème de 'ONLY_FULL_GROUP_BY` pour les versions supérieures de MySQL comme discuté ici: Error Code: 1055 incompatible with sql_mode=only_full_group_by