结合两个表的结果,按日期/小时区分

时间:2014-07-14 09:58:41

标签: mysql sql

我正在尝试计算结果。单独这两个查询工作正常,没有麻烦。

但是当我尝试将结果合并时(我已使用UNION)。我得到了正确的结果,但第二个表的结果附加到结果集。

例如

表一的结果:

当我使用简单查询时。

array(28) {
    [0]=> object(stdClass)#139 (7) { 
        ["date"]=> string(10) "2014-06-16"
        ["total"]=> string(1) "2"
        ["emails"]=> string(1) "0"
        ["calls"]=> string(1) "2"
        ["qualified"]=> string(1) "2"
    }
}

表二的结果:

array(28) {
    [0]=> object(stdClass)#139 (7) { 
        ["date"]=> string(10) "2014-06-16"
        ["no_answer"]=> string(1) "1"
        ["voicemail"]=> string(1) "1" 
    }
}

为了简化,每个结果只显示一个对象通知请注意,这两个结果来自同一日期,但它们在合并查询的结果集中添加了两次。

合并后的结果(使用当前功能):

array(28) {
    [0]=> object(stdClass)#139 (7) { 
        ["date"]=> string(10) "2014-06-16"
        ["total"]=> string(1) "2"
        ["emails"]=> string(1) "0"
        ["calls"]=> string(1) "2"
        ["qualified"]=> string(1) "2"
        ["no_answer"]=> string(1) "0"
        ["voicemail"]=> string(1) "0" 
    },

    [1]=> object(stdClass)#139 (7) { 
        ["date"]=> string(10) "2014-06-16"
        ["total"]=> string(1) "0"
        ["emails"]=> string(1) "0"
        ["calls"]=> string(1) "0"
        ["qualified"]=> string(1) "0"
        ["no_answer"]=> string(1) "1"
        ["voicemail"]=> string(1) "1" 
}

我想要的结果是:

在结果中我希望每个结果代表一个日期(没有重复的日期)。

    [0]=> object(stdClass)#139 (7) { 
        ["date"]=> string(10) "2014-06-16"
        ["total"]=> string(1) "2"
        ["emails"]=> string(1) "0"
        ["calls"]=> string(1) "2"
        ["qualified"]=> string(1) "2"
        ["no_answer"]=> string(1) "1"
        ["voicemail"]=> string(1) "1" 

完整功能

//Note: function is simplified

    function get_lead_numbers_by_distinct_days($num_days, $user_id){
        global $wpdb;
        $leads_table = 'leads';
        $calls_table = 'calls';


            $sql1 = "SELECT Date(date) date,
                    COUNT(type) total,
                    SUM(type='email') emails,
                    SUM(type='call') calls,
                    SUM(qualified=1) qualified,
                    SUM('') no_answer,
                    SUM('') voicemail

                    FROM $leads_table WHERE user_id = $user_id
                    AND DATE_SUB(CURDATE(), INTERVAL $num_days DAY) <= date

                    GROUP BY DATE(date)";


            $sql2 = "SELECT Date(date) date,
                    SUM('') total,
                    SUM('') emails,
                    SUM('') calls,
                    SUM('') qualified,
                    SUM(status='no-answer') no_answer,
                    SUM(status='machine') voicemail

                    FROM $calls_table WHERE user_id = $user_id
                    AND DATE_SUB(CURDATE(), INTERVAL $num_days DAY) <= date

                    GROUP BY DATE(date)";

            $sql = "$sql1

            UNION

            $sql2
            ";

            $data = $wpdb->get_results($sql);

        return $data;
    }

SUM()用于匹配列号。否则MySQL显示错误。

3 个答案:

答案 0 :(得分:0)

联盟应该已经奏效了。检查表中两个值的数据类型。如果你想将它们联合起来,它们必须是相同的。

答案 1 :(得分:0)

首先 - 如果你知道结果,你不需要总和。只需替换:

SUM('') no_answer,
SUM('') voicemail

0 no_answer,
0 voicemail

辅助 - 您通过2个单独的查询执行分组,为了获得完整的结果,您应该一起执行。

因此,您的组合查询应如下所示:

SELECT  Date(date) date,
        COUNT(type) total,
        SUM(type='email') emails,
        SUM(type='call') calls,
        SUM(qualified=1) qualified,
        SUM(status='no-answer') no_answer,
        SUM(status='machine') voicemail 
FROM (
    SELECT date, type, qualified, 0 status  
    FROM leads_table 
    WHERE user_id = $user_id
      AND DATE_SUB(CURDATE(), INTERVAL $num_days DAY) <= date

    UNION ALL 

    SELECT date, 0, 0 , status 
    FROM calls_table
    WHERE user_id = $user_id
      AND DATE_SUB(CURDATE(), INTERVAL $num_days DAY) <= date
) a
GROUP BY Date(date);

答案 2 :(得分:0)

最后不得不放弃UNION并使用JOIN代替。这是最后的查询。

                SELECT $leads_table.date date,
                COUNT($leads_table.type) total,
                SUM($leads_table.type='email') emails,
                SUM($leads_table.type='call') calls,
                SUM($leads_table.qualified=1) qualified,
                SUM($calls_table.status='no-answer') no_answer,
                SUM($calls_table.status='machine') voicemail

                FROM $leads_table
                LEFT JOIN $calls_table

                ON ($leads_table.object_id = $calls_table.ID)

                WHERE user_id = $user_id
                AND DATE_SUB(CURDATE(), INTERVAL $num_days DAY) <= date

                GROUP BY $group_by($leads_table.date)