问题如下:
假设我有一张这样的视图表(它是我正在使用的表格的子样本):
| col1 | col2 |
|------|------|
| 1 | a2 |
| 1 | b2 |
| 2 | c2 |
| 2 | d2 |
| 2 | e2 |
| 1 | f2 |
| 1 | g2 |
| 3 | h2 |
| 1 | j2 |
我需要添加两个新列
prev
包含col1
中之前的值,不等于当前的next
包含col1
中的下一个值,不等于当前的如果没有以前的值,则prev
应包含当前col1
的值,如果不存在下一个值,则next
应包含当前值。< / p>
结果应具有以下形式:
| col1 | col2 | prev | next |
|------|------|------|------|
| 1 | a2 | 1 | 2 |
| 1 | b2 | 1 | 2 |
| 2 | c2 | 1 | 1 |
| 2 | d2 | 1 | 1 |
| 2 | e2 | 1 | 1 |
| 1 | f2 | 2 | 3 |
| 1 | g2 | 2 | 3 |
| 3 | h2 | 1 | 1 |
| 1 | j2 | 3 | 1 |
我将不胜感激。
答案 0 :(得分:1)
如果我假设您有一个id
列指定了排序,那么这是可能的。我只是不确定使用窗口函数可以很容易地表达它。
您可以使用相关子查询:
select t.*,
(select t2.col1
from t t2
where t2.id < t.id and t2.col1 <> t.col1
order by t2.id desc
fetch first 1 row only
) as prev_col1,
(select t2.col1
from t t2
where t2.id > t.id and t2.col1 <> t.col1
order by t2.id asc
fetch first 1 row only
) as prev_col2
from t;
您可以为缺少的上一个和下一个值添加coalece()
。这不是问题的有趣部分。
答案 1 :(得分:1)
您可以使用窗口函数lead
,lag
,first_value
,last_value
和sum
的组合来尝试此操作。
select
t.col1, t.col2, n,
coalesce(first_value(y) over (partition by x order by col2), col1) prev_val,
coalesce(last_value(y2) over (partition by x order by col2
rows between current row and unbounded following), col1) next_val
from (
select
t.*,
case when col1 <> lag(col1) over (order by col2) then lag(col1) over (order by col2) end y,
case when col1 <> lead(col1) over (order by col2) then lead(col1) over (order by col2) end y2,
sum(n) over (order by col2) x
from (
select
t.*,
case when col1 <> lag(col1) over (order by col2) then 1 else 0 end n
from t
) t
) t;
它找到每组行的超前/滞后。
答案 2 :(得分:0)
WITH cte AS (
SELECT row_number() over() rowid, *
FROM unnest(array[1,1,2,2,2,1,1,3,1], array['a2','b2','c2','d2','e2','f2','g2','h2','j2']) t(col1,col2)
)
SELECT t.col1,
t.col2,
COALESCE(prev.col1,t.col1) prev,
COALESCE("next".col1,t.col1) "next"
FROM cte t
LEFT JOIN LATERAL (SELECT prev.col1
FROM cte prev
WHERE prev.rowid < t.rowid
AND prev.col1 != t.col1
ORDER BY prev.rowid DESC
LIMIT 1
) prev ON True
LEFT JOIN LATERAL (SELECT "next".col1
FROM cte "next"
WHERE "next".rowid > t.rowid
AND "next".col1 != t.col1
ORDER BY "next".rowid ASC
LIMIT 1
) "next" ON True