web-dev-qa-db-fra.com

Requête SQL avec avg et group by

J'ai quelques problèmes avec l'écriture d'une requête SQL pour MySQL. J'ai une table avec la structure suivante:

mysql> select id, pass, val from data_r1 limit 10;
+------------+--------------+----------------+
| id         | pass         | val            |
+------------+--------------+----------------+
| DA02959106 | 5.0000000000 |  44.4007000000 |
| 08A5969201 | 1.0000000000 | 182.4100000000 |
| 08A5969201 | 2.0000000000 | 138.7880000000 |
| DA02882103 | 5.0000000000 |  44.7265000000 |
| DA02959106 | 1.0000000000 | 186.1470000000 |
| DA02959106 | 2.0000000000 | 148.2660000000 |
| DA02959106 | 3.0000000000 | 111.9050000000 |
| DA02959106 | 4.0000000000 |  76.1485000000 |
| DA02959106 | 5.0000000000 |  44.4007000000 |
| DA02959106 | 4.0000000000 |  76.6485000000 |

Je veux créer une requête qui extrait les informations suivantes de la table:

id, AVG of 'val' for 'pass' = 1, AVG of 'val' for 'pass' = 2, etc

Le résultat de la requête devrait ressembler à ceci:

+------------+---------+---------+---------+---------+---------+---------+---------+
| id         | val_1   | val_2   | val_3   | val_4   | val_5   | val_6   | val_7   |
+------------+---------+---------+---------+---------+---------+---------+---------+
| DA02959106 | 186.147 | 148.266 | 111.905 | 76.3985 | 44.4007 | 0       | 0       |
+------------+---------+---------+---------+---------+---------+---------+---------+

avec plus de lignes pour chaque "id" unique, bien sûr. 

J'ai déjà essayé des requêtes comme

SELECT id, pass, AVG(val) AS val_1 FROM data_r1 WHERE pass = 1 GROUP BY id;

Cela renvoie le résultat correct, mais je dois le développer avec les résultats pour les autres valeurs possibles de 'pass' (jusqu'à 7).

J'ai essayé d'utiliser un SELECT imbriqué dans AVG, mais cela n'a pas fonctionné car je ne savais pas comment le limiter correctement à "l'identifiant" actuel.

J'ai ensuite créé Views pour représenter le résultat de chaque requête pour 'pass' = 1, 'pass' = 2, etc. Mais pour la plupart des identifiants, la valeur la plus élevée pour 'pass' est 5. Lorsque vous utilisez des requêtes JOIN pour obtenir le résultat final les vues J'ai reçu un jeu de résultats vide, car certaines des vues sont vides/n'ont pas de valeurs pour un "id" spécifique.

Des idées?

10
theFen

Si je comprends ce dont vous avez besoin, essayez ceci:

SELECT id, pass, AVG(val) AS val_1 
FROM data_r1 
GROUP BY id, pass;

Ou, si vous voulez juste une ligne pour chaque identifiant, ceci:

SELECT d1.id,
    (SELECT IFNULL(ROUND(AVG(d2.val), 4) ,0) FROM data_r1 d2 
     WHERE d2.id = d1.id AND pass = 1) as val_1,
    (SELECT IFNULL(ROUND(AVG(d2.val), 4) ,0) FROM data_r1 d2 
     WHERE d2.id = d1.id AND pass = 2) as val_2,
    (SELECT IFNULL(ROUND(AVG(d2.val), 4) ,0) FROM data_r1 d2 
     WHERE d2.id = d1.id AND pass = 3) as val_3,
    (SELECT IFNULL(ROUND(AVG(d2.val), 4) ,0) FROM data_r1 d2 
     WHERE d2.id = d1.id AND pass = 4) as val_4,
    (SELECT IFNULL(ROUND(AVG(d2.val), 4) ,0) FROM data_r1 d2 
     WHERE d2.id = d1.id AND pass = 5) as val_5,
    (SELECT IFNULL(ROUND(AVG(d2.val), 4) ,0) FROM data_r1 d2 
     WHERE d2.id = d1.id AND pass = 6) as val_6,
    (SELECT IFNULL(ROUND(AVG(d2.val), 4) ,0) FROM data_r1 d2 
     WHERE d2.id = d1.id AND pass = 7) as val_7
from data_r1 d1
GROUP BY d1.id
28
Marco

Si je comprends bien, vous voulez que la valeur moyenne de chaque identifiant soit respectée à chaque passage. La solution est

SELECT id, pass, avg(value) FROM data_r1
GROUP BY id, pass;
1