首页  >  问答  >  正文

如何在右连接的选择查询中添加一列

我正在尝试找到一种方法,将国家/地区代码添加到基于电话号码列的数据库通话记录中。我有一张表,其中包含国家及其拨号代码(称为国家/地区)。我可以查询所有记录并在后面添加国家/地区代码,但我需要能够对结果进行过滤和分页。

我正在使用一个我没有太多控制权的系统,因此向表添加新列或重写大块代码并不是真正的选择。这就是我必须处理的事情。

国家/地区表。

id 姓名 拨号代码
1 爱尔兰 353
2 美国 1

通话记录表。

id 开始日期时间 结束日期时间 route_id 电话号码 duration_秒
1 2014-12-18 18:51:12 2014-12-18 18:52:12 23 3538700000 60
2 2014-12-18 17:41:02 2014-12-18 17:43:02 43 18700000 120

路由表。

id 数字 已启用
23 1234567890 1
43 0987654321 1

我需要获取持续时间的总和值,所有唯一电话号码均按route_id、route_number 分组,但现在我们需要按country_id 对这些结果进行分组,以便我们可以按国家/地区对呼叫者进行分组。我使用下面的 mysql 查询来获取持续时间的总和值、唯一电话号码总数,所有这些值均按route_id、route_number 分组。该查询是另一位开发人员很久以前编写的。

SELECT 
    phone_number,
    route_number, 
    COUNT(callrecord_id) AS total_calls, 
    SUM(duration_sec) AS total_duration, 
    callrecord_join.route_id
FROM routes
RIGHT JOIN (
    SELECT 
        DATE(a.startdatetime) AS call_date, 
        a.id AS callrecord_id, 
        a.route_id AS route_id, 
        a.phonenumber AS phone_number,
        a.duration_seconds as duration_sec,
        b.inboundnumber AS route_number, 
    FROM callrecord AS a
    INNER JOIN routes AS b ON a.route_id = b.id
    WHERE DATE_FORMAT(a.startdatetime, '%Y-%m-%d') >= '2014-12-18' 
    AND DATE_FORMAT(a.startdatetime, '%Y-%m-%d') <= '2014-12-18' 
    AND b.isenabled = 1 
) AS callrecord_join ON routes.id = callrecord_join.route_id
GROUP BY route_id, route_number
LIMIT 10 offset 0;

我已经完成了在右侧联接表中添加country_id 的所有操作,以便我可以按country_id 进行分组。

我知道我可以使用 php 遍历每个国家/地区,并使用 where 子句获取结果,如下所示,但我无法对这些结果进行分页或轻松过滤它们。

左边(a.phonenumber, strlen($dialling_code)) = $dialling_code

如何使用国家/地区表将一列添加到包含国家/地区 ID 的联接表查询中,以便可以按路线 ID、路线编号和国家/地区 ID 进行分组?如下表所示。

id 开始日期时间 结束日期时间 route_id 电话号码 duration_秒 country_id
1 2014-12-18 18:51:12 2014-12-18 18:52:12 23 3538700000 60 1
2 2014-12-18 17:41:02 2014-12-18 17:43:02 43 18700000 120 2

P粉564192131P粉564192131283 天前384

全部回复(1)我来回复

  • P粉121447292

    P粉1214472922024-01-11 12:27:31

    routescallrecord_joinRIGHT JOIN 没有任何作用,因为您已经在之间有了 INNER JOIN子查询中的 routescallrecord,位于联接的右侧。

    您可以使用您所描述的联接 -

    JOIN countries c ON LEFT(a.phonenumber, LENGTH(c.dialling_code)) = c.dialling_code

    但它会给出相同的结果:

    JOIN countries c ON a.phonenumber LIKE CONCAT(c.dialling_code, '%')

    应该会稍微便宜一些。

    您应该测试对国家/地区的加入,以确保callrecord中的任何号码都不会加入多个国家/地区。某些国际拨号代码不明确,因此这取决于您使用的拨号代码列表。

    SELECT a.*, COUNT(*), GROUP_CONCAT(c.dialling_code)
    FROM callrecord a
    JOIN country c ON a.phonenumber LIKE CONCAT(c.dialling_code, '%')
    GROUP BY a.id
    HAVING COUNT(*) > 1;

    显然,如果您的数据集非常大,您将需要对上述查询进行批处理。

    我希望我没有过分简化事情,但根据我对你的问题的理解,查询只是:

    SELECT
        r.id AS route_id,
        r.number AS route_number,
        c.name AS country_name,
        SUM(a.duration_seconds) AS total_duration,
        COUNT(a.id) AS total_calls,
        COUNT(DISTINCT a.phonenumber) AS unique_numbers
    FROM callrecord AS a
    JOIN routes AS r ON a.route_id = r.id
    JOIN countries c ON a.phonenumber LIKE CONCAT(c.dialling_code, '%')
    WHERE a.startdatetime >= '2014-12-18' 
    AND a.startdatetime < '2014-12-19'
    AND r.isenabled = 1
    GROUP BY r.id, r.number, c.name
    LIMIT 10 offset 0;

    请注意,假设有合适的索引可用,请注意从 startdatetime 中删除 DATE_FORMAT() 以使这些条件可控制。

    回复
    0
  • 取消回复