[英]Ordering within group and selecting non-null values
我有一個表格,其中包含從多個來源合並的數據,我想:
x
分組z
列排序,首選非NULL
值NULL
值這是示例輸入,稱之為 table t
:
X | 是 | Z |
---|---|---|
一個 | a0 | NULL |
一個 | NULL | 1 |
一個 | a2 | 2 |
b | b1 | 1 |
b | b2 | 2 |
以及所需的 output:
X | 是 | Z |
---|---|---|
一個 | a2 | 1 |
b | b1 | 1 |
GROUP BY
和ORDER BY
我的第一個想法是使用GROUP BY
和ORDER BY
:
select x, min(y), min(z)
from t
group by x
order by y
但我明白了
ORA-00979: not a GROUP BY expression
B/c,IIUC,操作順序是GROUP BY
,然后是SELECT
聚合,然后是ORDER BY
,所以ORDER BY
只能對SELECT
中的內容進行操作。 那不是我想要的。
我確實設法通過FIRST_VALUE
獲得了所需的 output :
SELECT DISTINCT
x,
FIRST_VALUE(y IGNORE NULLS)
OVER(PARTITION BY x
ORDER BY
z
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) y,
FIRST_VALUE(z IGNORE NULLS)
OVER(PARTITION BY x
ORDER BY
z
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) z
FROM
t;
但這似乎非常冗長和重復。 有沒有更好的解決方案,可以指定一次window 而不是每列?
您可以使用match_recognize
捕獲具有非空值的行並在measures
子句中引用它們:
select x, y, z from test_tab match_recognize ( partition by x order by z asc nulls last measures /*The first value of Z (nulls last)*/ first(any_.z) as z, /*The first non-null value of Y: captured either by any_ pattern or by other that skips all nulls first */ coalesce(first(any_.y), first(other.y)) as y /*Any row followed by zero or more Y with null followed by any number of any non-null Y rows for the same X */ pattern (any_ y_null* other*) define y_null as y is null )
或者從Oracle 21c您可以通過在select
語句的底部聲明它來重用window 規范並使用您的原始方法:
select distinct x, first_value(y ignore nulls) over fv as y, first_value(z ignore nulls) over fv as z from test_tab window fv as ( partition by x order by z asc nulls last rows between unbounded preceding and unbounded following )
鑒於此示例數據:
create table test_tab(X, Y, Z) as select 'a', 'a0', NULL from dual union all select 'a', NULL, 1 from dual union all select 'a', 'a2', 2 from dual union all select 'b', 'b1', 1 from dual union all select 'b', 'b2', 2 from dual
兩個查詢都返回此結果:
X 是 Z 一個 a2 1 b b1 1
db<> 在這里擺弄
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.