我需要的是一个SQL查询,它可以报告来自聚合表和单数表的数据。我目前的数据库如下。
CREATE TABLE IF NOT EXISTS `faults_days` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`employee_id` int(11) NOT NULL,
`day_date` date NOT NULL,
`actioned_calls_out` int(11) NOT NULL,
`actioned_calls_in` int(11) NOT NULL,
`actioned_tickets` int(11) NOT NULL,
)
CREATE TABLE IF NOT EXISTS `faults_departments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(40) NOT NULL,
)
CREATE TABLE IF NOT EXISTS `faults_employees` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`team_id` int(11) NOT NULL,
`name` varchar(127) NOT NULL,
)
CREATE TABLE IF NOT EXISTS `faults_qos` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`qos_date` datetime NOT NULL,
`employee_id` int(11) NOT NULL,
`score` double NOT NULL,
)
CREATE TABLE IF NOT EXISTS `faults_teams` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`department_id` int(11) NOT NULL,
`name` varchar(40) NOT NULL,
)
Day
中的一行跟踪单个员工一天的表现(所接听的电话数,所处理的电话票数)。 Qos是衡量一天员工素质的指标(每天可以有多个Qos - 我需要获得的是平均分数)。此外,Qos可以在员工在数据库中没有性能条目的那天执行,并且仍然需要在报告中显示。
所需的最终结果是4份报告,显示按不同列分组的员工绩效。单个员工每天的绩效细分,员工在一段时间内的总体绩效,团队在一段时间内的表现,以及整个部门在一段时间内的表现。
我的问题是,我当前的查询有点复杂,需要对Day
数据和Qos
数据进行两次单独的查询。然后我的PHP应用程序在输出报告之前合并数据。 我想要的是一个单一查询,它可以返回总体效果和平均质量得分。
我必须向员工展示的当前查询是:
SELECT
`Employee`.`name` ,
`Team`.`name` ,
`Department`.`name` ,
SUM( `Day`.`actioned_calls_in` ) + SUM( `Day`.`actioned_calls_out` ) ,
SUM( `Day`.`actioned_tickets` )
FROM
`faults_days` AS `Day`
JOIN
`faults_employees` AS `Employee` ON `Day`.`employee_id` = `Employee`.`id`
JOIN
`faults_teams` AS `Team` ON `Employee`.`team_id` = `Team`.`id`
JOIN
`faults_departments` AS `Department` ON `Team`.`department_id` = `Department`.`id`
WHERE
`Day`.`day_date` >= '2011-06-01'
AND `Day`.`day_date` <= '2011-06-07'
GROUP BY `Employee`.`id`
WITH ROLLUP
和
SELECT
`Employee`.`name` ,
`Team`.`name` ,
`Department`.`name` ,
COUNT( `Qos`.`score` ) ,
AVG( `Qos`.`score` )
FROM
`faults_qos` AS `Qos`
JOIN
`faults_employees` AS `Employee` ON `Qos`.`employee_id` = `Employee`.`id`
JOIN
`faults_teams` AS `Team` ON `Employee`.`team_id` = `Team`.`id`
JOIN
`faults_departments` AS `Department` ON `Team`.`department_id` = `Department`.`id`
WHERE
`Qos`.`qos_date` >= '2011-06-01'
AND `Qos`.`qos_date` <= '2011-06-07'
GROUP BY `Employee`.`id`
WITH ROLLUP
我也尝试过简单地加入Qos表,但由于它返回了多行,因此会导致SUM()
总计混乱,并且由于缺少FULL OUTER JOIN
功能而出现问题。
修改
我用这个做了一些小的进展。看起来使用子查询是可行的方法,但我所做的一切都是纯粹的猜测。这是我到目前为止所得到的,如果Day
和Qos
表中都有一个条目,它只显示一行,这不是我想要的,我不知道如何扩展它包括上述各种分组。
SELECT
`Employee`.`name` ,
`Team`.`name` ,
`Department`.`name`,
`Day`.`Calls`,
`Day`.`Tickets`,
`Qos`.`NumQos`,
`Qos`.`Score`
FROM `faults_employees` AS `Employee`
JOIN
`faults_teams` AS `Team` ON `Employee`.`team_id` = `Team`.`id`
JOIN
`faults_departments` AS `Department` ON `Team`.`department_id` = `Department`.`id`
JOIN
(SELECT
`Day`.`employee_id` AS `eid`,
SUM(`Day`.`actioned_calls_in`) + SUM(`Day`.`actioned_calls_out`) AS `Calls`,
SUM(`Day`.`actioned_tickets`) AS `Tickets`
FROM `faults_days` AS `Day`
WHERE
`Day`.`day_date` = '2011-03-02'
GROUP BY `Day`.`employee_id`
) AS `Day`
ON `Day`.`eid` = `Employee`.`id`
JOIN
(SELECT
`Qos`.`employee_id` AS qid,
COUNT(`Qos`.`id`) AS `NumQos`,
AVG(`Qos`.`score`) AS `Score`
FROM `faults_qos` AS `Qos`
WHERE
`Qos`.`qos_date` = '2011-03-02'
GROUP BY `Qos`.`employee_id`
) AS `Qos`
ON `Qos`.`qid` = `Employee`.`id`
GROUP BY `Employee`.`id`
答案 0 :(得分:1)
您确实需要left join
和fault_qos
子查询中的fault_days
。即使在一个或两个中没有相应的行,这也会给你一个结果。 left join
表示该值在连接左边的表中是必需的,而不是右边的那个。我没有对此进行测试,现在已经很晚了,所以我可能没有想清楚,但是如果你将查询改为此,它应该可以工作:
SELECT
`Employee`.`name` ,
`Team`.`name` ,
`Department`.`name`,
`Day`.`Calls`,
`Day`.`Tickets`,
`Qos`.`NumQos`,
`Qos`.`Score`
FROM `faults_employees` AS `Employee`
JOIN
`faults_teams` AS `Team` ON `Employee`.`team_id` = `Team`.`id`
JOIN
`faults_departments` AS `Department` ON `Team`.`department_id` = `Department`.`id`
LEFT JOIN
(SELECT
`Day`.`employee_id` AS `eid`,
SUM(`Day`.`actioned_calls_in`) + SUM(`Day`.`actioned_calls_out`) AS `Calls`,
SUM(`Day`.`actioned_tickets`) AS `Tickets`
FROM `faults_days` AS `Day`
WHERE
`Day`.`day_date` = '2011-03-02'
GROUP BY `Day`.`employee_id`
) AS `Day`
ON `Day`.`eid` = `Employee`.`id`
LEFT JOIN
(SELECT
`Qos`.`employee_id` AS qid,
COUNT(`Qos`.`id`) AS `NumQos`,
AVG(`Qos`.`score`) AS `Score`
FROM `faults_qos` AS `Qos`
WHERE
`Qos`.`qos_date` = '2011-03-02'
GROUP BY `Qos`.`employee_id`
) AS `Qos`
ON `Qos`.`qid` = `Employee`.`id`
GROUP BY `Employee`.`id`