表我正试图从语音通话记录中获得分析结果。每次调用(一行)都有持续时间(以秒为单位)(只是int值,而不是datetime)。我试图获得分组数量为15秒的记录数量,如下所示:
+-------------------+
|Period | Count |
+-------------------+
| 0-15 | 213421 |
|15-30 | 231123 |
|30-45 | 1234 |
+-------------------+
期间开始为0,结束为86400。
我尝试了一些组合,为开始和结束设置变量,然后将它们递增15,但我不是很成功,我无法理解出现了什么问题。
请帮忙。谢谢!
答案 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