有没有办法在 RDBMS 中为每个呼叫客户的 CDR(呼叫数据记录)编写 sql 查询。?
Posted
技术标签:
【中文标题】有没有办法在 RDBMS 中为每个呼叫客户的 CDR(呼叫数据记录)编写 sql 查询。?【英文标题】:Is there a way to write sql query in RDBMS for CDR (Call Data Records) of every call customer makes.? 【发布时间】:2021-09-02 08:54:24 【问题描述】:这是我遇到的一个有趣的问题。 我有一张桌子
create table phonebook(
customer_id (varchar 30)
call_start_day (date)
call_end_day (date)
call_start_time (varchar 30)
call_end_time (varchar 30)
called_number (integer)
customer_call_location_city (varchar 30)
customer_call_location_state (varchar 30)
customer_call_location_zip (integer)
called_number_city (varchar 30)
called_number_state (varchar 30)
)
我需要根据过去 12 个月的平均每月 call_duration 找到前 n 个客户。 (仅考虑完整的月份,例如,如果当前日期是 2021-03-07,则过去 12 个月:2020-03-01 – 2021-02-28。每月通话时长 = 总和(通话时长),其中通话时长 = 时差call_end_day+ call_end_time 和 call_start_day+call_start_time)
解决方案- 我想找出时间,然后找出它们的平均值。有什么建议吗?
【问题讨论】:
我删除了不一致的标签,请只标记您正在使用的数据库。还提供样本数据和所需的输出 RDBMS 的日期操作/转换函数不一致。所以选择一个,然后我们可以回答这个问题。 谢谢@eshirvana 示例类似于 - call_start_day(日期),例如,2021-03-02 - call_end_day(日期),例如,2021-03-02 - call_start_time(varchar 30),例如, 14:21:15 - call_end_time (varchar 30),例如,14:30:11 我为此使用 SSMS(sql server),但对 Oracle 分析功能甚至是开放的:P 和示例数据应该包含所有列和 1 个额外的列将按平均通话时长排序 【参考方案1】:在 SQL Server 中,首先计算给出的表达式
您要考虑的第一个日期。 您要考虑的最后日期后的第二天。EOMONTH() 很适合这个。
SELECT DATEADD(DAY, 1, EOMONTH(GETDATE(),-1)) day_after_last,
DATEADD(DAY, 1, EOMONTH(GETDATE(), -13)) first
接下来,弄清楚如何获取通话时长。你还没有告诉我们你如何代表你的call_start_time
和call_end_time
,所以我们无法帮助你提供这个细节。因此,我将持续时间计算表示为存储函数。由您决定如何获得持续时间。可能以秒为单位的持续时间是获取呼叫详细信息记录的最佳方式。
专业提示永远不要使用 varchars 或 chars 来表示 DATE、TIME 或 DATETIME 数据。它们总是会导致混乱和悲伤。
这是要走的路。
SELECT TOP (5) customer_id,
AVG(dbo.duration(call_start_day, call_start_time,
call_end_day, call_end_time)) average
FROM phonebook
WHERE call_start_day >= DATEADD(DAY, 1, EOMONTH(GETDATE(), -13))
AND call_start_day < DATEADD(DAY, 1, EOMONTH(GETDATE(),-1))
GROUP BY customer_id
ORDER BY 2 DESC;
WHERE
子句仅提取具有您关心的日期的记录。
ORDER BY 2 DESC
子句表示按结果集的第二列从高到低排序。 TOP (5)
子句表示显示有序结果集的前五行。
编辑
如果您的时间列看起来像08:47:13
,那么您可以使用DATEDIFF() 计算持续时间。看起来是这样的
DATEDIFF(
second,
CAST(call_start_day AS DATETIME) + CAST(call_start_time AS DATETIME),
CAST(call_end_day AS DATETIME) + CAST(call_end_time AS DATETIME))
所以你的查询看起来像这样:
SELECT TOP (5) customer_id,
AVG(
DATEDIFF(
second,
CAST(call_start_day AS DATETIME) +
CAST(call_start_time AS DATETIME),
CAST(call_end_day AS DATETIME) +
CAST(call_end_time AS DATETIME))) average
FROM phonebook
WHERE call_start_day >= DATEADD(DAY, 1, EOMONTH(GETDATE(), -13))
AND call_start_day < DATEADD(DAY, 1, EOMONTH(GETDATE(),-1))
GROUP BY customer_id
ORDER BY 2 DESC;
【讨论】:
谢谢@O。琼斯,这是一个很好的解释。我的大部分疑虑都很清楚,甚至学到了一些新的 'EOMONTH()' 只是为了再添加 1 个场景,我需要检查 2020 年从 A 地到 B 地的月度呼叫率增长。呼叫应计入它开始的月份。 ` 增长率 = [(本月的#calls - 上个月的#calls)/上个月的#calls]。增长率应该从 2 月开始 `我使用上面的 datediff 进行了 call_duration_start_month 并与上个月的 call_duration 进行了联合。但它几乎没有错误。有什么建议吗? @O.Jones以上是关于有没有办法在 RDBMS 中为每个呼叫客户的 CDR(呼叫数据记录)编写 sql 查询。?的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在 kubernetes 部署(或 statefulset)中为每个 pod 创建一个持久卷?
有没有办法在 JOOQ 中为具有相同表结构的多个模式设置代码生成?
有没有办法在 Django 中为内联管理表单设置单独的页面?