如何使用单个 SQL 聚合函数查询为同一个聚合函数获取多个结果?
Posted
技术标签:
【中文标题】如何使用单个 SQL 聚合函数查询为同一个聚合函数获取多个结果?【英文标题】:How to get multiple results for the same aggregate function using a single SQL aggregate function query? 【发布时间】:2021-08-31 22:56:42 【问题描述】:我是 SQL 新手,我一直在尝试为我的数据库创建视图。 当我介绍聚合函数时,我很快就发现了这个问题;
所以在我的数据库中有两个表: 用户/员工数据表和组(例如“会计”、“支持”等)。
我想使用查询/视图为该组中的员工返回每个组的整个员工条目以及(该组的)最低/最高工资。
这是表格:
--- 员工数据---
CREATE TABLE `db_java-sql-hookup`.`tbl_employee-data` (
`ID_Employee` bigint UNIQUE NOT NULL AUTO_INCREMENT,
`fk_IDGroup` tinyint,
`EmployeeName` varchar(30) UNIQUE NOT NULL,
`Email` varchar(255) NOT NULL,
`Password` varchar(255) NOT NULL,
`Salary` int,
PRIMARY KEY (`ID_Employee`),
FOREIGN KEY (`fk_IDGroup`) REFERENCES `db_java-sql-hookup`.`tbl_groups`(`pk_IDGroup`)
);
INSERT INTO `db_java-sql-hookup`.`tbl_employee-data` (`EmployeeName`, `Email`, `Password`)
VALUES
("TestA", "TestA@web.com", "1234"),
("TestB", "TestB@web.com", "1234"),
("TestC", "TestC@web.com", "abcde"),
("TestD", "TestD@web.com", "0000"),
("TestE", "TestE@web.com", "g8t3");
### Set Groups ###
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `fk_IDGroup` = 1 WHERE `tbl_employee-data`.`ID_Employee` = 1;
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `fk_IDGroup` = 1 WHERE `tbl_employee-data`.`ID_Employee` = 2;
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `fk_IDGroup` = 1 WHERE `tbl_employee-data`.`ID_Employee` = 3;
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `fk_IDGroup` = 2 WHERE `tbl_employee-data`.`ID_Employee` = 4;
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `fk_IDGroup` = 2 WHERE `tbl_employee-data`.`ID_Employee` = 5;
### Set Salaries ###
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `Salary` = 1000 WHERE `tbl_employee-data`.`ID_Employee` = 1;
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `Salary` = 500 WHERE `tbl_employee-data`.`ID_Employee` = 2;
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `Salary` = 2000 WHERE `tbl_employee-data`.`ID_Employee` = 3;
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `Salary` = 750 WHERE `tbl_employee-data`.`ID_Employee` = 4;
UPDATE `db_java-sql-hookup`.`tbl_employee-data`
SET `Salary` = 300 WHERE `tbl_employee-data`.`ID_Employee` = 5;
---分组数据---
CREATE TABLE `db_java-sql-hookup`.`tbl_groups` (
`pk_IDGroup` tinyint UNIQUE NOT NULL AUTO_INCREMENT,
`GroupName` varchar(40) NOT NULL,
PRIMARY KEY (`pk_IDGroup`)
);
INSERT INTO `db_java-sql-hookup`.`tbl_groups` (`GroupName`)
VALUES
("Accounting"),
("Support"),
("Development"),
("Test");
之前,我处理过这些视图(我想将它们结合起来):
### MaxSalaryEmp ###
DROP VIEW IF EXISTS `db_java-sql-hookup`.`view_MaxSalaryEmployee`;
CREATE VIEW `db_java-sql-hookup`.`view_MaxSalaryEmployee` AS
SELECT `ID_Employee`, `EmployeeName`, `Salary`
FROM `db_java-sql-hookup`.`tbl_employee-data`
WHERE `Salary` =
(SELECT MAX(`Salary`) FROM `db_java-sql-hookup`.`tbl_employee-data`);
### Avg,Min,Max Group Salary ###
DROP VIEW IF EXISTS `db_java-sql-hookup`.`view_CombinedGroupSalary`;
CREATE VIEW `db_java-sql-hookup`.`view_CombinedGroupSalary` AS
SELECT `GroupName`,
AVG(`Salary`) AS `AvgSalary`,
MIN(`Salary`) AS `MinSalary`,
MAX(`Salary`) AS `MaxSalary`
FROM `db_java-sql-hookup`.`tbl_groups` AS grp
LEFT JOIN `db_java-sql-hookup`.`tbl_employee-data` AS emp
ON grp.`pk_IDGroup` = emp.`fk_IDGroup`
GROUP BY `GroupName`
ORDER BY `GroupName`;
我尝试过这样的事情:
SELECT `GroupName`, `ID_Employee`, `EmployeeName`, `Salary`,
MAX(`Salary`) AS `MaxSalary`
FROM `db_java-sql-hookup`.`tbl_groups` AS grp
LEFT JOIN `db_java-sql-hookup`.`tbl_employee-data` AS emp
ON grp.`pk_IDGroup` = emp.`fk_IDGroup`
GROUP BY `GroupName`
ORDER BY `GroupName`;
我希望最终结果如下所示: https://i.stack.imgur.com/xsmLT.png
(除了,它应该派出合适的员工而不是这里发生的任何事情)
提前谢谢你!
【问题讨论】:
【参考方案1】:我不清楚你想要完成什么。 您只想要每个组的***员工还是想要按组列出所有员工并显示每个组的最高薪水?
如果您希望每组一个条目,请使用您的组合工资视图,如下所示:
SELECT grp.`GroupName`, emp.`ID_Employee`, emp.`EmployeeName`, emp.`Salary`,
grp.`MaxSalary`
FROM `db_java-sql-hookup`.`view_CombinedGroupSalary` grp
LEFT JOIN `db_java-sql-hookup`.`tbl_employee-data` AS emp
ON grp.`pk_IDGroup` = emp.`fk_IDGroup` and grp.`MaxSalary` = emp.`Salary`
ORDER BY `GroupName`;
如果您需要列出所有员工,请执行以下操作:
SELECT grp.`GroupName`, emp.`ID_Employee`, emp.`EmployeeName`, emp.`Salary`,
cs.`MaxSalary`
FROM `db_java-sql-hookup`.`tbl_groups grp`
INNER JOIN `db_java-sql-hookup`.`view_CombinedGroupSalary cs
on grp.`pk_IDGroup` = cs.`pk_IDGroup`
LEFT JOIN `db_java-sql-hookup`.`tbl_employee_data` AS emp
ON grp.`pk_IDGroup` = emp.`fk_IDGroup`
ORDER BY grp.`GroupName`, emp.`EmployeeName`;
要使这些查询起作用,您需要在组合工资视图中包含 pk_IDGroup 列:
DROP VIEW IF EXISTS `db_java-sql-hookup`.`view_CombinedGroupSalary`;
CREATE VIEW `db_java-sql-hookup`.`view_CombinedGroupSalary` AS
SELECT `pk_IDGroup`,
`GroupName`,
AVG(`Salary`) AS `AvgSalary`,
MIN(`Salary`) AS `MinSalary`,
MAX(`Salary`) AS `MaxSalary`
FROM `db_java-sql-hookup`.`tbl_groups` AS grp
LEFT JOIN `db_java-sql-hookup`.`tbl_employee-data` AS emp
ON grp.`pk_IDGroup` = emp.`fk_IDGroup`
GROUP BY `pk_IDGroup`,`GroupName`
ORDER BY `GroupName`;
【讨论】:
非常感谢!第一个查询实际上正是我想要的。我不知道我也可以加入视图。【参考方案2】:对于这个问题,我认为你不需要使用 group by,而是需要使用“user-defined-variables”:
这个link 可以告诉你如何在 mysql 中按分区获取最大值(在 mssql 中它的工作方式不同)。
这是我需要删除“db_java-sql-hookup
”的 sql 小提琴中的问题 (sqlfiddle) 的解决方案。从表格中,您可以使用以下代码:
select `GroupName`, `ID_Employee`, `EmployeeName`, `Salary`,
@max:=IF(@custtype!=`GroupName`,`Salary`,@max),
@custtype:=`GroupName`
FROM (
select `GroupName`, `ID_Employee`, `EmployeeName`, `Salary`
FROM `db_java-sql-hookup`.`tbl_groups` AS grp
LEFT JOIN `db_java-sql-hookup`.`tbl_employee-data` AS emp
ON grp.`pk_IDGroup` = emp.`fk_IDGroup`
order by `GroupName`, `Salary` desc
) a, (select @max:=0, @custtype:='') t
如果您需要有关其工作原理的更多详细信息,请告诉我,我会添加它。
【讨论】:
以上是关于如何使用单个 SQL 聚合函数查询为同一个聚合函数获取多个结果?的主要内容,如果未能解决你的问题,请参考以下文章