使用mysql聚合函数min时获取正确的行数据?

cczfrluj  于 2021-06-21  发布在  Mysql
关注(0)|答案(3)|浏览(498)

这个问题在这里已经有答案了

sql仅选择列上具有最大值的行[重复](27个答案)
两年前关门了。
现在,据我所知,当您使用聚合函数时,例如 AVG , SUM 你必须记住,任何其他领域 SELECT 不包含在聚合函数中的将是不确定的,例如:

SELECT AVG(amount), name, desc FROM some_table;

我理解这一点,这是因为来自聚合函数的值没有绑定到任何一行,因此选择的其他字段是不确定的。
但是,如果使用不同类型的聚合函数,例如 MIN 或者 MAX 如果他们检索的内容绑定到某一行,那么可以安全地假设不在聚合函数中的任何其他选定字段都可以确定吗。。。与其他聚合函数结果不同,结果是否会绑定到特定的数据行?
例如:

SELECT MIN(media_id),
       auction_id,
       media_url
FROM   auction_media
WHERE  auction_id IN( 119925, 124660, 124663, 129078,
                      129094, 134395, 149753, 152221,
                      154733, 154737, 154742, 157694,
                      161411, 165965, 165973 )
       AND media_type = 1
       AND upload_in_progress = 0
GROUP  BY auction_id;

如果我的想法是正确的,那么它总是会返回正确的结果 media_url 正确的?

bjp0bcyl

bjp0bcyl1#

MIN 以及 MAX 和任何一排都没有关系 AVG 或者 SUM 是。所有4个都是聚合多行的结果,无论是所有行(如第一个查询)还是组中的行(如第二个查询)。
如果我的想法是正确的,这将总是返回正确的媒体地址,对吗?
不。如果您的数据是:

auction_id   media_id   media_url
119925       3          http://google.com
119925       5          http://yahoo.com
119925       3          http://bing.com

你的问题 SELECT MIN(media_id), auction_id, media_url GROUP BY auction_id 会回来的 3 为了 MIN(media_id) ,和 119925 为了 auction_id ,但是什么 media_url 它会回来吗? media_url 仍不确定。
你看,数据里没有这样的说法 media_url 在任何方面都与 media_id .
你可能(认为你)知道 media_url 对于一个特定的 media_id ,但这对sql引擎并不重要。

voase2hg

voase2hg2#

但是,如果您使用不同类型的聚合函数(如min或max),而它们检索的内容绑定到某一行,那么是否可以安全地假设可以确定不在聚合函数中的任何其他选定字段?
不。一方面,多行可以有最小值或最大值;另一方面,没有什么可以阻止一个查询同时选择min(a)、max(a)、avg(a)和sum(a)(我非常怀疑mysql是否会使它的查询引擎过于复杂,从而利用“如果查询只有一个聚合…”
注意:我很确定mysql最初允许这种查询的唯一原因是在以下情况下的缩写:

SELECT a.*, SUM(b.X)
FROM a INNER JOIN b ON a.PK = b.a_PK
GROUP BY a.PK;

如果查询作者知道未聚合字段是,则可以通过分组而不是聚合值来确定。

nsc4cvqm

nsc4cvqm3#

否。未聚合的列(不在 group by )在聚合查询中,查询来自任意和不确定的行。这种尴尬的行为就是为什么在大多数数据库中不允许使用这种语法,以及为什么mysql的最新版本在默认情况下“关闭它”。所以你的查询会返回一个错误。
有一种方法可以满足您的需求:

SELECT am.*
FROM auction_media am
WHERE auction_id IN (119925, 124660, 124663, 129078,
                      129094, 134395, 149753, 152221,
                      154733, 154737, 154742, 157694,
                      161411, 165965, 165973 ) AND
      media_type = 1 AND upload_in_progress = 0 AND
      media_id = (SELECT MIN(am2.media_id)
                  FROM auction_media m2
                  WHERE m2.auction_id = m.auction_id AND m2.media_type = m.media_type AND m2.upload_in_progress = m.upload_in_progress
                 );

对于性能,您需要一个索引 auction_media(auction_id, media_type, upload_in_progress, media_id) 以及 auction_media(media_type, upload_in_progress, auction_id) .

相关问题