每个组的本地最大值的 SQL 排序结果

Posted

技术标签:

【中文标题】每个组的本地最大值的 SQL 排序结果【英文标题】:SQL order results by local max of each group 【发布时间】:2020-05-29 15:47:53 【问题描述】:

我正在努力编写一个返回我想要的查询。 表:


|---------------------|------------------|------------------|------------------|
|   --  filename  --  |    --  url  --   |   -- pixels  --  |     -- id --     |
|---------------------|------------------|------------------|------------------|
|     myfilename1     |         url1     |         3100     |         1        |
|---------------------|------------------|------------------|------------------|
|     myfilename2     |         url1     |         1200     |         2        |
|---------------------|------------------|------------------|------------------|
|     myfilename3     |         url2     |         3000     |         3        |
|---------------------|------------------|------------------|------------------|
|     myfilename4     |         url3     |         4000     |         4        |
|---------------------|------------------|------------------|------------------|
|     myfilename5     |         url3     |         5000     |         5        |
|---------------------|------------------|------------------|------------------|

我想如何得到结果:

|---------------------|------------------|------------------|------------------|
|   --  filename  --  |    --  url  --   |   -- pixels  --  |     -- id --     |
|---------------------|------------------|------------------|------------------|
|     myfilename4     |         url3     |         4000     |         4        |
|---------------------|------------------|------------------|------------------|
|     myfilename5     |         url3     |         5000     |         5        |
|---------------------|------------------|------------------|------------------|
|     myfilename1     |         url1     |         3100     |         1        |
|---------------------|------------------|------------------|------------------|
|     myfilename2     |         url1     |         1200     |         2        |
|---------------------|------------------|------------------|------------------|
|     myfilename3     |         url2     |         3000     |         3        |
|---------------------|------------------|------------------|------------------|

基本上,我希望对结果进行排序,以便 url “组”在它们之间按像素排序,然后每个组在内部按 id 排序。正如您在我想要的结果表中看到的那样,像素列的最大值是 5000,所以“url3”组是第一个,它是按 id 排序的。然后是 url1 组,其局部最大值为第二高(3100)。

请注意,行数可能有数万行,还有更多行未图示,将来可能会添加更多行,因此硬编码的答案是无用的。 这意味着按 url 进行分页,因此查询还应支持按 url 而不是文件名的限制和偏移量(例如,返回属于此方法排序的第 20 个 url 的所有行)。 我试过按 MAX、OVER PARTITION 和类似的方式订购,但我就是不明白怎么做。

我的最新尝试因无法混合使用 MAX() 和 OVER PARTITION 而失败,因为我能想到的解决问题的唯一方法是对每个 url 的本地最大值进行分区。我怀疑可能有某种方法可以通过内部联接来做到这一点,但我只是不知道从哪里开始,因为 我需要选择整行,而不仅仅是一些列,所以我无法手动选择每一列。

【问题讨论】:

【参考方案1】:

您似乎想要order by 中的窗口函数:

order by max(pixels) over (partition by url) desc,
         url, id

【讨论】:

这给了我一个语法错误。我的查询是“SELECT * FROM WHERE ORDER BY MAX(pixels) OVER (PARTITION BY url) DESC, url, id;”。语法错误接近“OVER”。 事实证明,在 3.25 版本的 sqlite 中添加了窗口函数,而 debian 9 运行的是旧版本。一旦我设法升级我的服务器,我会报告。 最终回复:这适用于 sqlite > 3.25,谢谢。【参考方案2】:

如果您的 SQLite 版本不支持窗口函数,那么一种选择是使用聚合子查询连接表,该查询计算每个 url 的最大值 pixel,然后使用该信息对结果进行排序:

select t.*
from mytable t
inner join (select url, max(pixel) max_pixel from mytable group by url) m
    on t.url = m.url
order by m.max_pixel desc, url, id

【讨论】:

以上是关于每个组的本地最大值的 SQL 排序结果的主要内容,如果未能解决你的问题,请参考以下文章

SQL:查找每组的最大记录[重复]

SQL:查找每组的最大记录[重复]

返回 Netezza SQL 中每个组的最大值日期

如何编写 SQL 来选择具有每个组的最大值(值)的行?

当表很大时找到每个组的最大记录时如何优化sql?

oracle 查询每组的最大值