当使用SQL MIN()函数和GROUP BY时,任何其他列(不是MIN列,或GROUP BY列之一)是否匹配匹配MIN行中的数据?
例如,给定一个包含部门名称,员工姓名和薪水的表格:
SELECT MIN(e.salary), e.* FROM employee e GROUP BY department
显然,我会得到两个好的专栏,最低薪水和部门。员工姓名(以及任何其他员工字段)是否来自同一行?即MIN(薪水)行?
我知道很可能有两名员工的工资相同(且最低),但我所关心的(现在)所有的信息都是(或者一个)最便宜的员工。
这会选择最便宜的推销员吗?
SELECT min(salary), e.* FROM employee e WHERE department = 'sales'
基本上,我可以确定与MIN()函数一起返回的数据是否与具有该最小值的(或单个)记录相匹配?
如果数据库很重要,我正在使用MySql。
答案 0 :(得分:22)
如果你想在每个部门找到“最便宜”的员工,你会有两个选择:
SELECT
E.* -- Don't actually use *, list out all of your columns
FROM
Employees E
INNER JOIN
(
SELECT
department,
MIN(salary) AS min_salary
FROM
Employees
GROUP BY
department
) AS SQ ON
SQ.department = E.department AND
SQ.min_salary = E.salary
或者您可以使用:
SELECT
E.*
FROM
Employees E1
LEFT OUTER JOIN Employees E2 ON
E2.department = E1.department AND
E2.salary < E1.salary
WHERE
E2.employee_id IS NULL -- You can use any NOT NULL column here
第二个声明有效地说,向我展示所有员工,在同一个部门找不到另一个薪水较低的员工。
在这两种情况下,如果两名或两名以上员工的工资相等,那么他们(两者)都可以获得相同的工资。
答案 1 :(得分:1)
SELECT e.*
FROM employee e
WHERE e.id =
(
SELECT id
FROM employee ei
WHERE ei.department = 'sales'
ORDER BY
e.salary
LIMIT 1
)
要获取每个部门的值,请使用:
SELECT e.*
FROM department d
LEFT JOIN
employee e
ON e.id =
(
SELECT id
FROM employee ei
WHERE ei.department = d.id
ORDER BY
e.salary
LIMIT 1
)
要仅为拥有员工的部门获取值,请使用:
SELECT e.*
FROM (
SELECT DISTINCT eo.department
FROM employee eo
) d
JOIN
employee e
ON e.id =
(
SELECT id
FROM employee ei
WHERE ei.department = d.department
ORDER BY
e.salary
LIMIT 1
)
当然,在(department, salary)
上设置索引会大大改善所有三个查询。
答案 2 :(得分:0)
最快的解决方案:
SET @dep := '';
SELECT * FROM (
SELECT * FROM `employee` ORDER BY `department`, `salary`
) AS t WHERE IF ( @dep = t.`department`, FALSE, ( @dep := t.`department` ) OR TRUE );
答案 3 :(得分:0)
另一种方法可以是使用分析功能。这是使用分析和ROW_NUM函数的查询
select first_name,salary from(select first_name,salary,Row_NUMBER()over(PARTITION BY DEPARTMENT_ID ORDER BY salary ASC)as employee_count from employees)其中row_count = 1;