2009-04-10 5 views
0

Le tableau J'essaie d'obtenir un résultat analytique à partir de l'enregistrement des appels vocaux. Chaque appel (une ligne) a une durée en secondes (juste valeur int, pas datetime). Je suis en train d'obtenir nombre d'enregistrements regroupés par 15 secondes couvre comme ceci:Comptage des lignes dans l'étape SQL à l'aide du regroupement par variables incrémentielles

+-------------------+ 
|Period | Count  | 
+-------------------+ 
| 0-15 | 213421 | 
|15-30 | 231123 | 
|30-45 | 1234  | 
+-------------------+ 

mises en chantier de période est 0, fin est 86400.

J'ai essayé quelques combinaisons avec la définition des variables pour le démarrage et fin, puis les incrémenter de 15, mais je ne réussis pas très bien, et je ne peux pas comprendre ce qui ne va pas.

Veuillez nous aider. Je vous remercie!

+0

pas assez d'informations claires pour une réponse ... –

+0

Qu'est-ce que SGBDR utilisez-vous? – Quassnoi

Répondre

2

En MySQL:

SELECT CONCAT(span * 15, '-', span * 15 + 15), COUNT(*) AS cnt 
FROM (
     SELECT v.*, FLOOR(period/15) AS span 
     FROM voice_calls v 
     ) q 
GROUP BY 
     span 

MISE À JOUR:

La solution que vous AFFICHÉES travailler, en supposant qu'il y aura toujours plus de 5760 lignes.

Mais vous feriez mieux de créer un ensemble de lignes factice de 5760 lignes et l'utiliser dans OUTER JOIN:

CREATE TABLE spans (span INT NOT NULL PRIMARY KEY); 

INSERT 
INTO spans 
VALUES (0), 
     (1), 
     ... 
     (5759) 

SELECT span * 15, COUNT(*) 
FROM spans 
LEFT JOIN 
     calls 
ON  call.duration >= span * 15 
     AND call.duration < span * 15 + 15 
GROUP BY 
     span 

Il sera plus efficace et sain d'esprit, car il ne peut ni soupassement (si moins de 5760 lignes calls), ni prendre trop de temps s'il y a des millions de lignes là-bas.

+0

Jamais pensé à regarder la fonction FLOOR, cette requête semble très bien, mais malheureusement, cela ne fonctionne pas. # 1248 - Chaque table dérivée doit avoir son propre alias Apparemment, MySQL exige que toutes les tables dérivées d'avoir des alias –

+0

Un petit problème avec cette requête (à mon humble avis) - quand il n'y a pas de documents dans un groupe/span donné il n'y a pas de ligne à propos de ce groupe/span dans le résultat. –

+0

@ marko1980: oui, MySQL l'exige. – Quassnoi

0

Je pense qu'une requête comme celle-ci devrait fonctionner; Vous devrez faire pivoter les résultats vous-même sur l'écran si (par exemple, cette requête obtient les résultats horizontalement, vous devez les afficher verticalement):

SELECT 
    SUM(CASE WHEN CallLength BETWEEN 0 AND 15 THEN CallLength ELSE 0 END) AS ZeroToFifteen, 
    SUM(CASE WHEN CallLength BETWEEN 16 AND 30 THEN CallLength ELSE 0 END) AS FifteenToThirty 
FROM CallTable 

Mais après avoir relu la question, en mettant cas déclarations jusqu'à 86400 est probablement hors de question ... Eh bien :)

0

Cela a fonctionné enfin:

SET @a:=-15, @b:=0; 
SELECT t.start_time, t.end_time, count(c.duration) 
FROM calls c, 
     (
     SELECT (@a:[email protected]+15) as start_time, (@b:[email protected]+15) as end_time 
     FROM `calls` 
     GROUP BY 
       cdr_id 
     ) as t 
WHERE c.duration BETWEEN t.start_time and t.end_time 
GROUP BY 
     t.start_time, t.end_time 
+0

Cela fonctionnera si votre table contient toujours plus de 5760 lignes. – Quassnoi

+0

Bien que cela puisse fonctionner, vous devriez vraiment vérifier la performance par rapport à la méthode de Kouber. Vous adoptez essentiellement une approche procédurale et l'appliquez dans une base de données relationnelle conçue pour les opérations basées sur des ensembles. –

3

la requête suivante correspond à vos besoins:

SELECT 
    (duration - duration % 15), 
    COUNT(*) 
FROM 
    call 
GROUP BY 
    (duration - duration % 15) 
ORDER BY 
    1; 

Vous pouvez également ajouter une mise en forme de chaîne, dans le cas où vous avez besoin de la sortie exactement comme vous l'avez décrit:

SELECT 
    (duration - duration % 15)::text || '-' || (duration - duration % 15 + 15)::text, 
    COUNT(*) 
FROM 
    call 
GROUP BY 
    (duration - duration % 15) 
ORDER BY 
    1; 
Questions connexes