2011-02-17 4 views
2

J'ai une table avec 4 colonnes, id, Stream qui est le texte, Duration (int) et Timestamp (date/heure). Une ligne est insérée à chaque fois que quelqu'un joue un flux audio spécifique sur mon site Web. Stream est le nom, et Duration est le temps en secondes qu'ils écoutent. J'utilise actuellement la requête suivante pour comprendre en totale écouter heures pour chaque semaine pendant un an:GROUP BY avec plage de dates

SELECT YEARWEEK(`Timestamp`), (SUM(`Duration`)/60/60) FROM logs_main 
WHERE `Stream`="asdf" GROUP BY YEARWEEK(`Timestamp`); 

Ce fait ce que j'attends ... présentant un total de temps pour écouter chaque semaine dans l'année où il est Les données.

Cependant, je voudrais construire une requête où j'ai une ligne de résultat pendant des semaines qu'il n'y a peut-être aucune donnée. Par exemple, si la 26ème semaine de 2006 n'a pas de lignes qui tombent dans cette semaine, alors je voudrais que le résultat SUM soit 0.

Est-ce possible? Peut-être via un JOIN sur une plage de dates en quelque sorte?

Répondre

2

La solution d'une vieille école éprouvée est de mettre en place une autre table avec un tas de plages de dates que vous pouvez joindre à l'extérieur pour le regroupement (comme dans l'autre table aurait toutes les semaines avec un début/date de fin).

Dans ce cas, vous pouvez simplement obtenir avec une table complète des valeurs de YEARWEEK:

201100 
201101 
201102 
201103 
201104 

Et voici une esquisse d'une instruction SQL:

SELECT year_weeks.yearweek , (SUM(`Duration`)/60/60) 

FROM year_weeks LEFT OUTER JOIN logs_main 
    ON year_weeks.yearweek = logs_main.YEARWEEK(`Timestamp`) 

WHERE `Stream`="asdf" GROUP BY year_weeks.yearweek; 
+0

Merci. J'ai fini par trouver une autre solution (complètement différente de ce que j'ai demandé, sinon je posterais ici), mais je vais simplement utiliser cette méthode dans le futur. C'est dommage qu'il n'y ait pas moyen de générer directement cet ensemble de données de YEARWEEK dans la requête. – Brad

0

Voici une suggestion. pourrait ne pas être exactement ce que vous cherchez.

Mais que vous aviez une table simple avec une colonne [year_week] qui contenait les valeurs de 1, 2, 3, 4 ... 52

Vous pouvez ensuite théoriquement:

SELECT 

A.year_week, 
(SELECT SUM('Duration')/60/00) FROM logs_main WHERE 
stream = 'asdf' AND YEARWEEK('TimeStamp') = A.year_week GROUP BY YEARWEEK('TimeStamp')) 

FROM 

tblYearWeeks A 

cela doit évidemment quelques ajustements ... J'ai fait plusieurs requêtes similaires dans d'autres projets et cela fonctionne assez bien selon la situation.

Si vous êtes à la recherche d'une solution à base d'une table/sql, alors cela m'intéresse aussi!

+0

Je pourrais manquer quelque chose, mais je ne vois pas où vous vous joignez à tblYearWeeks ... – RQDQ

+0

ce n'est pas une jointure. C'est une sous-requête de tblyearweeks qui garantit que tous les enregistrements des telyearweeks sont retournés, puis la somme de la durée est renvoyée par la sous-requête. – Patrick