【问题标题】:Percent with SUM of a SUM in MySQLMySQL 中 SUM 的百分比
【发布时间】:2015-11-07 17:21:09
【问题描述】:

干杯。

我需要计算所选年份每个部门的总薪水的百分比。

SELECT D.dept_name AS 'Department', SUM(S.salary) AS 'Total', CONCAT(ROUND(SUM(SUM(S.salary)), 2), '%') AS '%'
FROM departments D INNER JOIN dept_emp DE ON D.dept_no=DE.dept_no INNER JOIN  salaries S ON DE.emp_no=S.emp_no
WHERE (S.from_date<='2000-01-01') AND (S.to_date>='2000-12-31')
GROUP BY D.dept_name

我试过了,但它不起作用;它说: 错误代码1111,SQL状态HY000:组函数使用无效

SUM(SUM()) 对我来说听起来很可疑,但我没有想法。

如果您需要,这里是表格:

REATE TABLE employees (
    emp_no      INT             NOT NULL,
    birth_date  DATE            NOT NULL,
    first_name  VARCHAR(14)     NOT NULL,
    last_name   VARCHAR(16)     NOT NULL,
    gender      ENUM ('M','F')  NOT NULL,    
    hire_date   DATE            NOT NULL,
    PRIMARY KEY (emp_no)
);

CREATE TABLE departments (
    dept_no     CHAR(4)         NOT NULL,
    dept_name   VARCHAR(40)     NOT NULL,
    PRIMARY KEY (dept_no),
    UNIQUE  KEY (dept_name)
);

CREATE TABLE dept_emp (
    emp_no      INT             NOT NULL,
    dept_no     CHAR(4)         NOT NULL,
    from_date   DATE            NOT NULL,
    to_date     DATE            NOT NULL,
    KEY         (emp_no),
    KEY         (dept_no),
    FOREIGN KEY (emp_no)  REFERENCES employees   (emp_no)  ON DELETE CASCADE,
    FOREIGN KEY (dept_no) REFERENCES departments (dept_no) ON DELETE CASCADE,
    PRIMARY KEY (emp_no,dept_no)
);

CREATE TABLE salaries (
    emp_no      INT             NOT NULL,
    salary      INT             NOT NULL,
    from_date   DATE            NOT NULL,
    to_date     DATE            NOT NULL,
    KEY         (emp_no),
    FOREIGN KEY (emp_no) REFERENCES employees (emp_no) ON DELETE CASCADE,
    PRIMARY KEY (emp_no, from_date)
); 

【问题讨论】:

  • 你的怀疑是对的。给我们适当的 DDL 和期望的结果

标签: mysql


【解决方案1】:

有几种方法可以获得指定的结果。

一种方法是使用内联视图来获取所有部门的总工资。例如,这样的查询:

  SELECT SUM(ts.salary) AS `tot`
    FROM departments td
    JOIN dept_emp    te ON td.dept_no = te.dept_no
    JOIN salaries    ts ON te.emp_no=ts.emp_no

您可以在另一个查询中引用该查询的结果,方法是将其包装成括号并将其包含在表名的位置。必须为内联视图分配别名。 (在 MySQL 中,这被称为“派生表”。)

例如:

SELECT D.dept_name                           AS `Department`
     , SUM(S.salary)                         AS `Total`
     , MAX(t.tot)                            AS `total_all_departments`
     , ROUND(SUM(S.salary)/MAX(t.tot)*100,0) AS `pct`
  FROM departments D
  JOIN dept_emp    DE ON DE.dept_no = D.dept_no
  JOIN salaries    S  ON S.emp_no = DE.emp_no
 CROSS
  JOIN ( 
         SELECT SUM(ts.salary) AS `tot`
           FROM departments td
           JOIN dept_emp    te ON td.dept_no = te.dept_no
           JOIN salaries    ts ON te.emp_no=ts.emp_no
       ) t
 WHERE S.from_date <= '2000-01-01'
   AND S.to_date   >= '2000-12-31'
 GROUP BY D.dept_name

这不是唯一的方法。例如,您还可以在 SELECT 列表中使用子查询。还有其他方法可以工作,但其中一些方法依赖于为某些表中的行提供唯一标识符。在演示之前,我们需要一些表定义。

【讨论】:

  • 我知道你做了什么,这是计算总数的好方法,但由于某种原因 pct 始终为 0 >
  • 可能是执行计算的表达式。确保返回“每个部门”和“所有部门”的总薪水的两个表达式返回正确的值。下一步将添加一个表达式,对两者进行除法(以获得分数)。一旦你明白了,就修改表达式以获取舍入和格式。
【解决方案2】:

已解决

我对@Spencer7593 解决方案做了一些修改:

SELECT D.dept_name                           AS `Department`
     , SUM(S.salary)                         AS `Total`
     , MAX(t.tot)                            AS `total_all_departments`
     , ROUND((SUM(S.salary)/MAX(t.tot)))*100 AS `pct`
  FROM departments D
  JOIN dept_emp    DE ON DE.dept_no = D.dept_no
  JOIN salaries    S  ON S.emp_no = DE.emp_no
 CROSS
  JOIN ( 
         SELECT SUM(ts.salary) AS `tot`
           FROM departments td
           JOIN dept_emp    te ON td.dept_no = te.dept_no
           JOIN salaries    ts ON te.emp_no=ts.emp_no
           WHERE ts.from_date <= '2000-01-01'
           AND ts.to_date   >= '2000-12-31'
       ) t
 WHERE S.from_date <= '2000-01-01'
   AND S.to_date   >= '2000-12-31'
 GROUP BY D.dept_name

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 2013-03-22
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    相关资源
    最近更新 更多