【问题标题】:Change MySQL query from WHERE to LEFT JOIN将 MySQL 查询从 WHERE 更改为 LEFT JOIN
【发布时间】:2014-09-23 16:41:12
【问题描述】:

我有一个查询报告 Asterisk 呼叫使用情况和队列统计信息。该查询目前使用 MySQL WHERE 子句来连接表和过滤数据。

这是查询目前的样子:

SELECT 
    c.name as 'Agent',
    e.extended_number AS 'Extension',
    COUNT(ql.`time`) AS 'Total Inbound Calls',
    (SELECT 
            COUNT(1) 
    FROM
        call_history ch,
        ast_queue_mstatus qm
    WHERE
        ch.start >= (DATE_SUB(DATE(NOW()),
            INTERVAL 10050 MINUTE))
            AND ch.start <= (DATE(NOW()))
            AND ch.calltype = 'out'
            AND ch.flow = 'out'
            AND ch.extension_number = qm.membername
            AND qm.membername = e.extended_number
    GROUP BY qm.membername) AS 'Total Outbound Calls',
    FORMAT(SUM(CAST(ql.arg2 AS UNSIGNED)) / 60, 2) AS 'Total Inbound Duration',
    FORMAT(AVG(CAST(ql.arg2 AS UNSIGNED)) / 60, 2) AS 'Avg Inbound Duration',
    FORMAT(AVG(CAST(ql.arg1 AS UNSIGNED)) / 60, 2) AS 'Avg Caller Hold Time'
FROM
    ast_queue_log ql,
    ast_queue_mstatus qs,
    client c,
    extension e
WHERE
    ql.queuename = '1234'
    AND ql.`time` >= (DATE_SUB(DATE(NOW()), INTERVAL 7 DAY))
    AND ql.`time` <= (DATE(NOW()))
    AND (ql.event = 'COMPLETEAGENT'
    OR ql.event = 'COMPLETECALLER'
    OR ql.event = 'COMPLETETRANSFER')
    AND RIGHT(ql.agent, 8) = qs.membername
    AND qs.membername = e.extended_number
    AND e.client_id = c.id      
GROUP BY ql.agent
ORDER BY c.name;

我遇到的问题是我需要返回未收到任何呼入电话的队列成员的呼出结果。目前如果ast_queue_log 中没有记录,那么WHERE 子句会排除这些记录,这意味着它们不会被标量子查询拾取。

如何更改此查询,以便从call_history 获取所有呼叫记录,其中ast_queue_mstatus 中有相应记录?

对不起,如果这太复杂或没有足够的信息,如果这没有意义,我可以尝试简化!

【问题讨论】:

  • 我给出了答案,但现在我看到答案的核心(将条件从哪里移动到左连接)已经在您的标题中。让我想知道:如果你已经知道了,为什么还要问?
  • @GolezTrol 感谢您的回答,我问这个问题的原因是我知道左连接是答案,但无法理解语法和所需内容。您的回答非常有帮助,我希望今天下午实施 :)

标签: mysql join left-join asterisk


【解决方案1】:

是时候放弃那些旧的逗号分隔的表列表并使用 1992 年引入的连接标准(是的)。 :-)

因为那时您可以使用LEFT JOIN。使用这种连接,关系是可选的。也就是说,返回第一个表中的所有行(如果它们与 WHERE 子句中的条件匹配),但连接表也不必有记录。 如果不是,则仍会返回一行,但字段中会填充NULL 值。

SELECT 
    c.name as 'Agent',
    e.extended_number AS 'Extension',
    COUNT(ql.`time`) AS 'Total Inbound Calls',
    (SELECT 
        COUNT(1) 
    FROM
        call_history ch
        INNER JOIN ast_queue_mstatus qm 
          ON qm.membername = ch.extension_number
    WHERE
        ch.start >= (DATE_SUB(DATE(NOW()), INTERVAL 10050 MINUTE))
        AND ch.start <= (DATE(NOW()))
        AND ch.calltype = 'out'
        AND ch.flow = 'out'
        AND ch.extension_number = e.extended_number
    GROUP BY 
       ch.extension_number) AS 'Total Outbound Calls',
    FORMAT(SUM(CAST(ql.arg2 AS UNSIGNED)) / 60, 2) AS 'Total Inbound Duration',
    FORMAT(AVG(CAST(ql.arg2 AS UNSIGNED)) / 60, 2) AS 'Avg Inbound Duration',
    FORMAT(AVG(CAST(ql.arg1 AS UNSIGNED)) / 60, 2) AS 'Avg Caller Hold Time'
FROM
    client c,
    INNER JOIN extension e 
        ON e.client_id = c.id
    INNER JOIN ast_queue_mstatus qs 
        ON qs.membername = e.extended_number
    LEFT JOIN ast_queue_log ql 
        ON ql.queuename = '1234'
        AND ql.`time` >= (DATE_SUB(DATE(NOW()), INTERVAL 7 DAY))
        AND ql.`time` <= (DATE(NOW()))
        AND (
            ql.event = 'COMPLETEAGENT'
            OR ql.event = 'COMPLETECALLER'
            OR ql.event = 'COMPLETETRANSFER')
        AND RIGHT(ql.agent, 8) = qs.membername
GROUP BY ql.agent
ORDER BY c.name;

您也可以使用RIGHT JOIN 反过来加入(第一个表是可选的)。但总的来说,这很难解释。

【讨论】:

    猜你喜欢
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 2016-05-27
    相关资源
    最近更新 更多