使用增量变量分组计算SQL语句中的行

时间:2009-04-10 11:35:16

标签: sql

表我正试图从语音通话记录中获得分析结果。每次调用(一行)都有持续时间(以秒为单位)(只是int值,而不是datetime)。我试图获得分组数量为15秒的记录数量,如下所示:

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

期间开始为0,结束为86400。

我尝试了一些组合,为开始和结束设置变量,然后将它们递增15,但我不是很成功,我无法理解出现了什么问题。

请帮忙。谢谢!

4 个答案:

答案 0 :(得分:3)

以下查询符合您的需求:

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

您还可以添加一些字符串格式,以防您需要完全按照您所描述的输出:

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

答案 1 :(得分:2)

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

<强>更新

您发布的解决方案将起作用,假设总有超过5760行。

但您最好创建5760行的虚拟行集并在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

它会更有效率和理智,因为它既不会下溢(如果5760中的行少于calls),也不会花费很多时间,如果那里有数百万行。

答案 2 :(得分:0)

我认为像这样的查询应该有效;您必须自己在显示器上显示结果(例如,此查询水平获取结果,您必须垂直显示它们):

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

但是在重新阅读这个问题后,将案例陈述高达86400可能是不可能的......哦,好吧:)

答案 3 :(得分:0)

这终于奏效了:

SET @a:=-15, @b:=0;
SELECT  t.start_time, t.end_time, count(c.duration)
FROM    calls c,
        (
        SELECT  (@a:=@a+15) as start_time, (@b:=@b+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