2013-05-01 5 views
1

Voici une requête que j'essaie de lancer.mysql: erreur étrange 1111 utilisation invalide du groupe par

select location_data.trip_code,sum(max(device_time)-min(device_time)) from location_data,trip_management 
where location_data.source_id=3 and location_data.trip_code=trip_management.trip_code 
group by location_data.trip_code 

il y a différents voyages identifiés par trip_code dans les deux trip_managemnet et les voyages location_data de tables.these sont prises par un seul utilisateur identifié de manière unique (source_id =) 3. ce que j'essaye de faire ici est de faire la somme de toutes les différences de temps pour chaque voyage et de le convertir en hh: mm: ss en utilisant la fonction sec_to_time pour afficher le temps total pris par l'utilisateur 3 pour effectuer tous ses déplacements. Le problème avec la requête ci-dessus est qu'il génère l'erreur 1111 dès que j'applique sum() sur la différence de max et min device_time de chaque déclenchement. Je ne peux pas me permettre une sous-requête parce que c'est en soi une sous-requête dans une requête plus grande. Je souhaite que j'ai bien expliqué le problème.

Répondre

3

Le problème ici est que vous essayez d'appliquer un agrégat SUM() sur les agrégats MAX(),MIN(), mais en fait, les deux niveaux fonctionnent sur des groupes différents. L'interne se regroupe sur location_data.trip_code, et l'externe se regroupe sur le résultat de cela. Vous aurez besoin de l'envelopper dans un sous-requête:

SELECT 
    trip_code, 
    /* Outer query sums the inner aggregates */ 
    SUM(max_time - min_time) AS time_sum 
FROM (
    SELECT 
    location_data.trip_code, 
    /* Inner aggregates return the max & min times only */ 
    max(device_time) AS max_time, 
    min(device_time) AS min_time 
    FROM 
    location_data, 
    INNER JOIN trip_management ON location_data.trip_code = trip_management.trip_code 
    WHERE 
    location_data.source_id=3 
    GROUP BY location_data.trip_code 
) first_group 
GROUP BY trip_code 

Je vous ai également remplacé implicitement vous joindre à un INNER JOIN explicite, qui est la syntaxe préférée de nos jours.

+0

merci beaucoup :) mais j'espérais éviter une sous-requête pour atteindre les résultats. Comme je l'ai mentionné, cette requête initself est une sous-requête dans une requête plus grande. Avoir des sous-requêtes imbriquées entraînera une diminution des performances, n'est-ce pas? Y a-t-il un moyen d'éviter la sous-requête en gardant le schéma tel qu'il est? – Salik

+0

@ user1451836 Une sous-requête FROM ne peut pas vraiment être évitée dans cette situation car les clauses 'GROUP BY' doivent être appliquées dans différents contextes. La performance ici ne sera pas aussi mauvaise que si vous les avez fait comme des sous-sélections dans le 'SUM()'. Cela pourrait être des ordres de grandeur plus lents. Votre autre option consisterait à mettre en cache la sous-requête en tant que vue matérialisée, si elle ne change pas souvent. –

+0

vues ne fonctionnera pas parce que les données entrantes sont en temps réel, et pour créer des vues, cela ajoutera un peu plus de complexité au système. Donc, je suppose que c'est la réponse à ma question. merci Michael :) – Salik

Questions connexes