Sql 执行MIN然后GROUP BY后,ID值丢失。为什么?

Sql 执行MIN然后GROUP BY后,ID值丢失。为什么?,sql,group-by,indexing,greatest-n-per-group,aggregate-functions,Sql,Group By,Indexing,Greatest N Per Group,Aggregate Functions,为了简化,如果我有一个名为“employee”的表: id INT NOT NULL PRIMARY KEY, salary FLOAT, department VARCHAR(255) 我想执行并查询在哪里检索每个部门的最低工资。 我的问题是这样的: SELECT employee.ID, MIN(employee.salary), employee.department FROM employee GROUP BY employee.department 但不管找到了哪些记录。结果集中的

为了简化,如果我有一个名为“employee”的表:

id INT NOT NULL PRIMARY KEY,
salary FLOAT,
department VARCHAR(255)
我想执行并查询在哪里检索每个部门的最低工资。 我的问题是这样的:

SELECT employee.ID, MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department
但不管找到了哪些记录。结果集中的ID值重命名为1,2,3。。。。但结果集中存在多个记录部门


执行“聚合”功能和“分组依据”后,如何维护员工的实际ID?

这将实现以下目的:

SELECT employee.department, MIN(employee.salary), employee.ID
FROM employee
GROUP BY 1

您的脚本无效:

SELECT employee.ID, MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department
相反,看看这个:

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

如果您还需要员工id,则需要使用子查询。

您不能。试想一下,如果一个部门有20名员工,而该部门有三名员工的最低工资相同,那么您希望查询输出显示哪个EmployeeId?如果保证每个部门只有一名员工具有最低工资,则可以通过选择特定的员工记录来实现,其中工资是每个部门的最低值:

Select EmployeeID
From Employee e
Where Salary = 
      (Select Min(Salary) From EMployee
       Where DepartmentId = e.DepartmentId)

但当一个以上的员工具有该最低工资水平时,每个部门将返回多个记录

在现代SQL Server版本和其他功能相当强大的现代SQL引擎中,SQL窗口函数可能是比子查询和自连接更好的选择,以满足您的需求:

  SELECT ID, salary, department
  FROM employee
  WHERE 1 = ROW_NUMBER() OVER(PARTITION BY department ORDER BY salary ASC)

如果多个员工拥有相同的部门最低工资,您只需要其中一个员工,您可以通过以下方式向订单中添加标准:如果您希望根据某些特定标准选择一个员工;如果您想要全部,请查看排名,而不是行数。

我猜您使用的是MySQL或SQLite,因为您的查询不明确,标准SQL或大多数品牌的RDBMS都不允许使用。MySQL和SQLite更为宽松,因此您有责任解决歧义

以下是我通常的解决方法:

SELECT e1.ID, e1.salary, e1.department
FROM employee e1
LEFT OUTER JOIN employee e2 ON (e1.department = e2.department
    AND e1.salary > e2.salary)
WHERE e2.department IS NULL;
下面是另一个给出相同结果的解决方案:

SELECT e1.ID, e1.salary, e1.department
FROM employee e1
JOIN (SELECT e2.department, MIN(e2.salary) AS min_salary
      FROM employee e2 GROUP BY e2.department) d
  ON (e1.salary = d.min_salary);

如果部门中有多个员工具有相同的最低工资,则这两项都会为每个部门提供多行。您需要决定如何解决该问题,因为从您的问题描述中还不清楚。

@Am,我查看了您的sql,。。我承认我不熟悉这个语法,Group By 1是什么意思?是否按表中的第一个序号属性进行分组?还是通过常量值?它是按顺序值进行分组的,但在第二次测试中,字段类型和顺序都会有所不同。包括采购订单的代码,所以nvm。我猜这取决于服务器类型…@Am,我猜,因为我不知道你的数据库是什么工作的,但是在标准SQL中,如果它工作的话,那就用一个常量值整数1分组,这意味着你应该只得到一行,所有部门的最低工资,而不是每个部门的最低工资…@Charles:我使用的是mysql,我确信这是select中字段的顺序。因为我得到了超过1行,什么服务器?神谕mySql。。添加了每个组最大n个标记,即使这是在寻找每个组最小的标记。但这是同一类问题,在StackOverflow的其他几十个问题中都有涉及。唉,MySQL目前不支持ROW_NUMBER。@比尔,没错-我确实指定了相当强大和现代的;-。我从OP上看不到任何迹象表明他正在使用旧的或非标准的SQL实现,或者,哪种,如果他是的话,所以我给出了标准的SQL答案shd关于PostgreSQL、SQL Server、Oracle、IBM DB2等的工作。是的,我只是为我正在编写的书研究了这一点。除了Informix和InterBase之外,大多数商业RDBMS都支持窗口函数。在开源厂商中,PostgreSQL 8.4和Apache Derby 10.4支持窗口功能;不是MySQL、SQLite、Firebird等,因此第二个查询似乎不起作用。也许我在某些方面错了,但您似乎在JOIN SELECT e2.department的ON子句中缺少条件e1.department=d.department,…:它应该在e1.department=d.department和e1.salary=d.minu salary上,您认为我对吗?