涉及聚合数据的 MySQL 连接

标签 mysql

我需要的是一个 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< 而出现问题 功能。

编辑: 我在这方面取得了一些的进展。看起来使用子查询是可行的方法,但我所做的一切都是纯粹的猜测。到目前为止,这是我得到的,如果 DayQos 表中都有一个条目,它只会显示一行,这不是我想要的,我'我不知道如何扩展它以包括上述各种分组。

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`

最佳答案

您确实需要 fault_qosfault_days 子查询上的 left join。即使一个或两个中没有相应的行,这也会给你一个结果。 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`

关于涉及聚合数据的 MySQL 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6398393/

相关文章:

mysql - 使用 Hibernate HQL 的嵌套查询

php - 准确保存和显示文本的输入和提交方式

mysql - 当搜索需要更具体时,如何在 MySQL 中使用 like 函数或在 mysql 中运行 LIKE 命令

mysql - 在mysql中使用varchar(14)作为日期时间

mysql - 将 SELECT DISTINCT ON 查询从 Postgresql 转换为 MySQL

mysql - 使用 EntityFramework 在运行时更改数据库类型

java - 在mysql中创建表时出现SQLException

mysql - 自动递增十六进制值

mysql - 搜索模式和替换

php - 如何将一个值插入到不同的行