24

当使用 SQL MIN() 函数以及 GROUP BY 时,任何其他列(不是 MIN 列或 GROUP BY 列之一)是否与匹配的 MIN 行中的数据匹配?

例如,给定一个包含部门名称、员工姓名和薪水的表:

SELECT MIN(e.salary), e.* FROM employee e GROUP BY department

显然我会得到两个很好的列,最低工资和部门。员工姓名(和任何其他员工字段)是否来自同一行?即具有 MIN(salary) 的行?

我知道很可能有两名员工的薪水相同(且最低),但我(现在)所关心的只是获取有关(或一名)最便宜员工的所有信息。

这会选择最便宜的推销员吗?

SELECT min(salary), e.* FROM employee e WHERE department = 'sales'

本质上,我可以确定与 MIN() 函数一起返回的数据将与具有该最小值的(或单个)记录匹配吗?

如果数据库很重要,我正在使用 MySql。

4

4 回答 4

23

如果您想在每个部门中获得“最便宜”的员工,您将有两个选择:

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

第二个语句有效地告诉我,向我展示在同一部门找不到另一位薪水较低的员工的所有员工。

在这两种情况下,如果两名或多名员工的最低工资相同,您将获得他们(全部)。

于 2009-04-06T20:36:07.630 回答
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)将大大改善所有三个查询。

于 2009-04-06T20:25:44.783 回答
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 );
于 2012-07-17T19:43:18.890 回答
0

另一种方法是使用分析函数。这是使用分析和 ROW_NUM 函数的查询

选择 first_name,salary from (select first_name,salary, Row_NUMBER() over (PARTITION BY DEPARTMENT_ID ORDER BY Salary ASC) as row_count from employees) where row_count=1;

于 2017-02-20T22:02:35.250 回答