2016-11-24 78 views
2

我想知道是否有可能到另一列添加到包含像最小值,最大值聚合函数select语句...SQL MIN函数和其他列

例如:

SELECT user_id, MAX(salary) FROM users; 

这个语句是否正确在sql标准中(在mysql的工作中); 它在mysql中的工作,但我想我读的地方,如果我把一个聚合函数在select子句中,我不能放任何东西,但聚合函数或如果有一个组,通过分组列可以在选择条款(在MySQL)


EDIT

User(user_id, name, last_name, salary) 

我想选择从Useruser_id, name, (maximum salary column);有没有可能做到没有子查询?

用户表

User_id, Name, Salary 

| 1 | user1 | last1 | 500 | | 
|---|-------|-------|------|---| 
| 2 | user2 | last2 | 1000 | | 
| 3 | user3 | last3 | 750 | | 
| |  |  |  | | 

输出必须user_id, username, lastname, and salary of the user who have the max salary,所以这里的输出中必须做到:

2 user2 last2 1000 

+0

取决于你想要做什么,MySQL does not folllow ansi标准关于聚合函数和组,所以你可以做一些不允许在其他数据库中的快捷方式。 –

+0

@scaisEdge它使用group by,它会返回每个元组user_id的最大值(工资),这与使用'SELECT user_id,name,salary'相同。 – karim

+1

btw您应该向我们展示示例数据和预期输出。这个问题可以根据你的需要改变。 –

回答

1

告诉你有这取决于你想要什么不同的解决方案....

没有GROUP BY,无子查询,轻松蛋糕

select * 
from users 
ORDER BY salary DESC 
LIMIT 1 
1

让我们来看一个例子:

mysql> select * from users; 
+---------+----------+ 
| user_id | salary | 
+---------+----------+ 
|  1 | 42000.00 | 
|  2 | 39000.00 | 
|  3 | 50000.00 | 
+---------+----------+ 

mysql> SELECT user_id, MAX(salary) FROM users; 
+---------+-------------+ 
| user_id | MAX(salary) | 
+---------+-------------+ 
|  1 | 50000.00 | 
+---------+-------------+ 

那是怎么回事?用户1不是薪水为50000.00的用户。

mysql> SELECT user_id, MAX(salary), MIN(SALARY) FROM users; 
+---------+-------------+-------------+ 
| user_id | MAX(salary) | MIN(SALARY) | 
+---------+-------------+-------------+ 
|  1 | 50000.00 | 39000.00 | 
+---------+-------------+-------------+ 

用户1也不是39000.00的用户。这是越来越腥,对吗?

当您使用聚合函数时,它们只适用于您使用该函数的列。user_id列不会奇迹般地知道哪个最大值来自哪行,并显示相应的user_id。

在那个例子中,我查询MAX和MIN工资。但是这些属于不同的用户!哪个user_id应该显示,即使user_id可以自动从聚合值来自的行中?

如果两个用户有相同的薪水,这与最高薪水并列,会出现什么情况?应显示哪个user_id?

如果您使用不返回任何单行上存在的值的聚合函数,该怎么办?

mysql> SELECT user_id, AVG(salary) FROM users; 
+---------+--------------+ 
| user_id | AVG(salary) | 
+---------+--------------+ 
|  1 | 43666.666667 | 
+---------+--------------+ 

下面是解释:聚合函数导致结果减少到一行后,读取整个行组。不在聚合函数内的列(如user_id)从行组中的某个任意行获取其值。任意并不意味着随机在实践中,它往往是该组中第一个MySQL行读取。但不能保证永远是这样。

这个有用吗?不是特别的。在其他数据库中,这不是一个有效的查询,它会从字面上产生一个错误。

事实上,MySQL 5.7改变了行为,通过强制执行不允许模棱两可的查询的规则。如果试图在MySQL 5.7运行上面的查询,它会产生一个错误:

ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'test.users.user_id'; this is incompatible with sql_mode=only_full_group_by

有使它像早期版本的MySQL的一个选项。有关这方面的更多信息,请参阅:https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

作为一个小问题,SQLite是允许这种任意结果的另一个数据库。只有在SQLite中,user_id的值将来自组中读取的最后一个行。去搞清楚。

+1

感谢您提供这个有价值的答案,但您能否为我解决这个问题? – karim

+1

我非常喜欢这个解释。查询中非聚合user_id的误解不可能变得更加明显。 –

+0

@卡里姆,胡安卡洛斯给出了最简单的解决方案。 –

2

首先:没有,

SELECT user_id, MAX(salary) FROM users; 

不符合标准。您正在使用不具有GROUP BY子句的聚合函数(MAX)。通过这样做,您可以告诉DBMS将所有记录聚合到一个结果行。现在你告诉DBMS在这个结果行中显示什么?表中找到的最高工资(MAX(salary))和user_id。但是,没有user_id;表中可能有许多不同的user_id。这违反了SQL标准。 MySQL可以自由地将非聚合的user_id解释为任意user_id(任意挑选)。

所以即使查询运行,它的结果通常不是所需的结果。

这个查询:

SELECT user_id, name, MAX(salary) FROM users GROUP BY user_id; 

,另一方面是符合标准的。让我们再看看这个查询的作用:这一次有GROUP BY子句告诉DBMS你想要一个结果行,每user_id。对于您要显示的每个user_iduser_id,name和最大值salary。所有这些都是有效的表达; user_iduser_id本身名称是与user_id关联的一个用户名,而最大值salary是用户的最高工资。允许使用未分类的列name,因为它在功能上依赖于分组user_id。但是,许多DBMS不支持这一点,因为确定一个表达式在功能上是否依赖于该组可能会变得非常复杂。

至于如何以最高工资显示用户记录,您需要一个限制条款。 MySQL为此提供了LIMIT,它可以为您提供前n行。但它并不处理关系。

SELECT * FROM users ORDER BY salary DESC LIMIT 1; 

SELECT * FROM users ORDER BY salary FETCH FIRST ROW ONLY; 
标准SQL

不过,为了应对关系,在

SELECT * FROM users ORDER BY salary FETCH FIRST ROW WITH TIES; 

你需要在MySQL子查询,因为LIMIT不支持这一点:

SELECT * FROM users WHERE salary = (SELECT MAX(salary) FROM users);