【问题标题】:Finding the Max of multiple elements in the same column在同一列中查找多个元素的最大值
【发布时间】:2019-02-16 10:09:52
【问题描述】:

表 A 由 A.i、A.j 和 A.val 给出。 A 构成一个 3x3 矩阵。

我需要从 A.val 中找到 Max(A.val) 的 ij, i+1j, ij+1,i-1j, ij-1(如果存在)。但是,我找不到任何解决方案来查找同一列的特定元素的最大值。请帮忙。

示例:

i   |   j   |   val
0       0       7
0       1       5
0       2       8
1       0       10
1       1       7
1       2       7
2       0       2
2       1       0
2       2       5

答案输出:

我 | j |值

0       0       10
0       1       8
0       2       8
1       0       10
1       1       10
1       2       8
2       0       10
2       1       7
2       2       7

【问题讨论】:

  • 请编辑您的问题以显示示例数据和预期输出,以便我们确保了解您的要求。另外,您能否用您正在使用的 RDBMS(oracle、mysql、sql-server、...)标记您的问题?
  • 结果集是什么?我不知道我是否真的理解这个问题。是整个表格一个值还是每个单元格一个值?

标签: sql sqlite


【解决方案1】:

我能想到的唯一合理的解释是你想要四个相邻单元格中的最大值加上当前单元格。让我假设您的数据库支持greatest(),因为这样可以简化问题:

select t.*,
       greatest(val,
                lag(val, 1, val) over (order by i),
                lead(val, 1, val) over (order by i),
                lag(val, 1, val) over (order by j),
                lead(val, 1, val) over (order by j)
               ) as neighborly_maximum                
from t;

你也可以用左连接来做到这一点:

select t.*,
           greatest(val,
                    coalesce(tup.val, val),
                    coalesce(tdown.val, val),
                    coalesce(tleft.val, val),
                    coalesce(tright.val, val)
                   ) as neighborly_maximum                       
from t left join
     t tup
     on tup.i = t.i and tup.j = t.j + 1 left join
     t tdown
     on tdown.i = t.i and tdown.j = t.j - 1 left join
     t tleft
     on tleft.i = t.i - 1 and tleft.j = t.j left join
     t tright
     on tright.i = t.i + 1 and tright.j = t.j;

【讨论】:

  • 在“OVER”附近获取(sqlite3.OperationalError):语法错误
【解决方案2】:

使用 SQLite >= 3.25 (2018),您可以使用 window functionsLAG()LEAD() 让您访问邻居记录。然后,core function MAX() 可用于计算值列表的最大值。

SELECT
    i,
    j,
    MAX(
        val,
        COALESCE(LEAD(val) OVER(PARTITION BY j ORDER BY i), 0), -- i+1 / j
        COALESCE(LAG(val)  OVER(PARTITION BY j ORDER BY i), 0), -- i-1 / j
        COALESCE(LEAD(val) OVER(PARTITION BY i ORDER BY j), 0), -- i   / j+1
        COALESCE(LAG(val)  OVER(PARTITION BY i ORDER BY j), 0)  -- i   / j-1
    ) res
FROM mytable

这个 DB fiddle demo on SQLite 3.26 与您的示例数据返回:

| i   | j   | res |
| --- | --- | --- |
| 0   | 0   | 10  |
| 0   | 1   | 8   |
| 0   | 2   | 8   |
| 1   | 0   | 10  |
| 1   | 1   | 10  |
| 1   | 2   | 8   |
| 2   | 0   | 10  |
| 2   | 1   | 7   |
| 2   | 2   | 7   |

在 SQLite 的早期版本中,一种解决方案是进行 4 个连接,如下所示:

SELECT
    t.i,
    t.j,
    MAX(
        t.val, 
        COALESCE(t1.val, 0), 
        COALESCE(t2.val, 0), 
        COALESCE(t3.val, 0), 
        COALESCE(t4.val, 0)
    ) res
FROM mytable t
LEFT JOIN mytable t1 ON t.i = t1.i + 1 AND t.j = t1.j 
LEFT JOIN mytable t2 ON t.i = t2.i - 1 AND t.j = t2.j 
LEFT JOIN mytable t3 ON t.i = t3.i     AND t.j = t3.j + 1
LEFT JOIN mytable t4 ON t.i = t4.i     AND t.j = t4.j - 1

Demo on db fiddle

【讨论】:

  • 在“OVER”附近获取(sqlite3.OperationalError):语法错误
  • @StevenChoi:你使用的是哪个版本的 sqlite?
  • @StevenChoi :用 SQLite 的解决方案更新了我的答案
  • ipython-sql 0.3.9
  • 感谢在以前的版本示例中完美运行
猜你喜欢
  • 2016-05-24
  • 1970-01-01
  • 2016-10-04
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 2014-07-21
  • 1970-01-01
相关资源
最近更新 更多