在同一列中查找多个元素的最大值

时间:2019-02-16 01:04:24

标签: sql sqlite

表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

答案输出:

i | 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

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

使用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