【问题标题】:I need to calculate the average production per employee per month我需要计算每个员工每月的平均产量
【发布时间】:2019-06-27 01:21:56
【问题描述】:

我需要创建一个报告,显示平均每天至少生产 30 件的员工

我有两张桌子:

Employees: id, name, surname
Production: id, date_time, id_employee, [..], quantity_produced

员工表中的 id = 生产表中的 id_employee


SELECT name, surname, Avg(quantity_produced), Month(data_ora) Mnth
FROM production inner join employees on employees.id = production.id_employee
GROUP BY name, quantity_produced, Month(date_time);

select name, surname, quantity_produced, avg(quantity_produced) as avgentrypermonth 
    from (
select month(date_time) as month ,count(1) as quantity
     group by month(date_time));

select name, surname, quantity_produced
    from production 
     inner join employees on employees.id = production.id_employee
    where avg(quantity_produced) > 30;

【问题讨论】:

  • 你需要对所有年份的所有月份进行 AVG 吗????
  • 给定查询有什么问题?您能分享一下目前可行的方法以及您需要帮助的地方吗?

标签: mysql sql mysql-workbench


【解决方案1】:

我很可能会从以下查询中选择一个。

但如果没有示例数据和预期结果,很难提出可靠的建议。

查询:

SELECT 
    Production.id_employee,
    AVG(Production.quantity_produced)
FROM 
    Production
WHERE
    Production.date_time BETWEEN
                         (LAST_DAY(NOW()) + INTERVAL 1 DAY) - INTERVAL 1 MONTH # first day of current month
                         AND
                         LAST_DAY(NOW()) # last day of current month
GROUP BY 
    Production.id_employee

查询何时需要员工记录:

SELECT 
    Employees.name,
    Employees.surname,
    AVG(Production.quantity_produced)
FROM 
    Production
INNER JOIN 
    Employees ON Production.id_employee = Employees.id
WHERE
    Production.date_time BETWEEN
                         (LAST_DAY(NOW()) + INTERVAL 1 DAY) - INTERVAL 1 MONTH  # first day of current month
                         AND
                         LAST_DAY(NOW()) # last day of current month
GROUP BY 
    Employees.id

请注意,上面的查询至少假定 MySQL 5.7.5+ 和 SQL 1999+ 标准可选功能称为functional dependency

manual

或作为共同相关的子查询:正确索引时应该没问题

SELECT 
    (SELECT Employees.name FROM Employees.id = Production.id_employee) AS name,
    (SELECT Employees.surname FROM Employees.id = Production.id_employee) AS surname,
    AVG(Production.quantity_produced)
FROM 
    Production
WHERE
    Production.date_time BETWEEN
                         (LAST_DAY(NOW()) + INTERVAL 1 DAY) - INTERVAL 1 MONTH # first day of current month
                         AND LAST_DAY(NOW()) # last day of current month
GROUP BY 
    Production.id_employee

【讨论】:

    【解决方案2】:

    在处理月份时,您应该确保将年份也考虑在内:

    SELECT year(p.data_ora) as yyyy, month(p.data_ora) as mm,
           e.name, e.surname, avg(p.quantity_produced),
    FROM production p inner join
         employees e
         on e.id = p.id_employee
    GROUP BY year(p.data_ora), month(p.data_ora,
             e.name, e.surname
    HAVING avg(p.quantity_produced) >= 30
    ORDER BY year(p.data_ora), month(p.data_ora),
             e.name, e.surname;
    

    这假设production 拥有员工每天生产的数量。

    注意事项:

    • 当您的表引用多个表时,限定所有列引用。
    • 使用表别名,以便查询更易于编写和阅读。
    • 记住这一年! (当你工作几个月时)

    【讨论】:

      【解决方案3】:

      过滤聚合结果需要有子句

      SELECT name, surname, Avg(quantity_produced), Month(date_time) Mnth
      FROM production 
      inner join employees on employees.id = production.id_employee
      GROUP BY name, surname, Month(date_time)
      having Avg(quantity_produced) > 30 ;
      

      还有年份

      SELECT name, surname, Avg(quantity_produced), Month(date_time) Mnth, year(date_time) year
      FROM production 
      inner join employees on employees.id = production.id_employee
      GROUP BY name, surname, Month(date_time), year(date_time) year
      having Avg(quantity_produced) > 30 ;
      

      【讨论】:

        【解决方案4】:
            I think this should work , can you please try it once. And may be little modification required, Comment here I will try to do the fixes.
          1.Select
                 E.id "Employee ID",
                 E.name "Employee Name",
                 Month(P.date_time) "Month",
                 AVG(P.quantity_produced) "Quantity Produced"
            From Employee as E
                 Join Production as P on E.id=P. id_employee
            Group by
                 E.id,E.name,Month(P.date_time)
            Having Avg(P.quantity_produced) > 30
        
        2.Select
                 E.name "Employee Name",
                 Month(P.date_time) "Month",
                 AVG(P.quantity_produced) "Quantity Produced"
            From Employee as E
                 Join Production as P on E.id=P. id_employee
            Group by
                 E.name,Month(P.date_time)
            Having Avg(P.quantity_produced) > 30
        

        【讨论】:

        • 公平警告:以上查询假定至少 MySQL 5.7.5+ 和 SQL 1999+ 标准可选功能,称为functional dependency...参见manual
        • 我是根据 MS SQL Server 标准编写的。
        • 那么你的 SQL 应该会失败,因为 SQL Server 不支持这些关闭查询,因为 E.name 不在 GROUP BY 中。SQL Server 不支持函数依赖
        • 非常感谢您的指出。你是对的。我会按部分添加到组中。
        • 据我了解,如果我们只在两个地方(分组和选择)都取 ID,那么它的性能会更好。因为大多数时候 id 是主键(或者你可以说聚集索引),它会使其更快。输入名称会使它有点慢。你怎么看。
        猜你喜欢
        • 2019-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多