2011-07-23 49 views
3

我目前有一个相当混乱的查询,它从多个涉及两个子查询的表中连接数据。我现在要求将这些数据按DAY(),WEEK(),MONTH()QUARTER()分组。通过多个连接的日期范围进行MySQL分组

我有三个表格:days,qosemployees。一个employee是不言自明的,day是一个员工在给定的一天的表现,qos是一个随机的质量检查,可以每天执行很多次。

目前,我选择所有employeesLEFT JOIN ing dayqos,这很好。但是,现在,我需要对数据进行分组,以便在某个日期范围内细分团队或个人的表现。

以这样的数据:

雇员

id | name 
------------------ 
1 | Bob Smith 

id | employee_id | day_date | calls_taken 
--------------------------------------------- 
1 | 1   | 2011-03-01 | 41 
2 | 1   | 2011-03-02 | 24 
3 | 1   | 2011-04-01 | 35 

的Qos

id | employee_id | qos_date | score 
---------------------------------------- 
1 | 1   | 2011-03-03 | 85 
2 | 1   | 2011-03-03 | 95 
3 | 1   | 2011-04-01 | 91 

如果我是通过分组通过DAY()开始,我需要看到以下结果:

Day__date | Day__Employee__id | Day__calls | Day__qos_score 
------------------------------------------------------------ 
2011-03-01 | 1     | 41   | NULL 
2011-03-02 | 1     | 24   | NULL 
2011-03-03 | 1     | NULL  | 90 
2011-04-01 | 1     | 35   | 91 

正如你看到的,Day__calls应该SUM(calls_taken)Day__qos_scoreAVG(score)。我尝试过使用与上面类似的方法,但由于直到其中一个表已加入时才知道日期,因此只会显示保存有day的记录。

有没有办法做到这一点,或者我会以错误的方式处理事情?

编辑:按照要求,这是我到目前为止所提出的。但是,它只显示有day的日期。

SELECT COALESCE(`day`.day_date, qos.qos_date)  AS Day__date, 
     employee.id         AS Day__Employee__id, 
     `day`.calls_taken       AS Day__Day__calls, 
     qos.score         AS Day__Qos__score 
FROM faults_employees `employee` 
     LEFT JOIN (SELECT `day`.employee_id     AS employee_id, 
         SUM(`day`.calls_taken)    AS `calls_in`, 
       FROM faults_days AS `day` 
       WHERE employee.id = 7 
       GROUP BY (`day`.day_date) 
     ) AS `day` 
     ON `day`.employee_id = `employee`.id 
     LEFT JOIN (SELECT `qos`.employee_id AS employee_id, 
         AVG(qos.score) AS `score` 
       FROM faults_qos qos 
       WHERE employee.id = 7 
       GROUP BY (qos.qos_date) 
     ) AS `qos` 
     ON `qos`.employee_id = `employee`.id AND `qos`.qos_date = `day`.day_date 
WHERE employee.id = 7 
GROUP BY Day__date 
ORDER BY `day`.day_date ASC 
+0

你能发表您的查询吗? –

+0

@Christian我已经添加了我目前的查询 –

回答

2

我正在添加了貌似解决方案:

SELECT 
    `date`, 
    `employee_id`, 
    SUM(`union`.`calls_taken`) AS `calls_taken`, 
    AVG(`union`.`score`) AS `score` 
FROM (-- select from union table 
    (SELECT -- first select all calls taken, leaving qos_score null 
     `day`.`day_date` AS `date`, 
     `day`.`employee_id`, 
     `day`.`calls_taken`, 
     NULL AS `score` 
    FROM `employee` 
    LEFT JOIN 
     `day` 
      ON `day`.`employee_id` = `employee`.`id` 
    ) 
    UNION -- union both tables 
    (
    SELECT -- now select qos score, leaving calls taken null 
     `qos`.`qos_date` AS `date`, 
     `qos`.`employee_id`, 
     NULL AS `calls_taken`, 
     `qos`.`score` 
    FROM `employee` 
    LEFT JOIN 
     `qos` 
      ON `qos`.`employee_id` = `employee`.`id` 
    ) 
) `union` 
GROUP BY `union`.`date` -- group union table by date 

对于UNION工作,我们要设置在qos表中dayqos_score场和calls_taken场为空。如果我们不这样做,calls_takenscore将被UNION语句选中到同一列中。 在此之后,我选择了union_d表中汇总函数SUM()AVG()所需的字段,并按照联合表中的date字段进行分组。

+2

+1与我即将发布的解决方案完全相同,但是您击败了我!澄清为什么需要UNION:[如何模拟MySQL中的全外连接](http://www.xaprb.com/blog/2006/05/26/how-to-write-full-outer-join-in -mysql /) – Mike

+1

感谢您澄清这是一个'完整的外部连接'! – mAu

+0

@mAu(and @Mike)+1谢谢你好先生,你已经救了无数小时了! –