[英]Oracle SQL - Get latest value of each column
Suppose I have a table that looks like this:假设我有一个看起来像这样的表:
There are 2 ISIN's in the table (ISIN 1 and 2).表中有 2 个 ISIN(ISIN 1 和 2)。 If you look at the first row, you'll see that all fields are filled with values.
如果您查看第一行,您会看到所有字段都填满了值。 In the second row there is only one field filled, which represents an update of the field (all empty fields didn't changed).
在第二行中只有一个字段被填充,代表该字段的更新(所有空字段都没有改变)。
Basically I want the latest value of each field (grouped by ISIN).基本上我想要每个字段的最新值(按 ISIN 分组)。
I was thinking of creating a Materialized view, if there is a build-in function or an easy way to achive my result.如果有内置的 function 或实现我的结果的简单方法,我正在考虑创建一个物化视图。 If there is not, I'll create a pipe function and iterate over the records.
如果没有,我将创建一个 pipe function 并遍历记录。
You can use the LAST_VALUE
analytic function:您可以使用
LAST_VALUE
解析 function:
SELECT ts,
id,
isin,
value1,
value2,
value3,
value4,
value5,
value6
FROM (
SELECT ts,
id,
isin,
LAST_VALUE(value1) IGNORE NULLS OVER ( PARTITION BY isin ORDER BY ts, id ) AS value1,
LAST_VALUE(value2) IGNORE NULLS OVER ( PARTITION BY isin ORDER BY ts, id ) AS value2,
LAST_VALUE(value3) IGNORE NULLS OVER ( PARTITION BY isin ORDER BY ts, id ) AS value3,
LAST_VALUE(value4) IGNORE NULLS OVER ( PARTITION BY isin ORDER BY ts, id ) AS value4,
LAST_VALUE(value5) IGNORE NULLS OVER ( PARTITION BY isin ORDER BY ts, id ) AS value5,
LAST_VALUE(value6) IGNORE NULLS OVER ( PARTITION BY isin ORDER BY ts, id ) AS value6,
ROW_NUMBER() OVER ( PARTITION BY isin ORDER BY ts DESC, id DESC ) AS rn
FROM table_name
)
WHERE rn = 1
or, you can use MAX()... KEEP ( DENSE_RANK... )
:或者,您可以使用
MAX()... KEEP ( DENSE_RANK... )
:
SELECT MAX(ts) AS ts,
MAX(id) KEEP ( DENSE_RANK LAST ORDER BY ts, id ) AS id,
isin,
MAX(value1) KEEP (
DENSE_RANK FIRST
ORDER BY
CASE WHEN value1 IS NOT NULL THEN ts END DESC NULLS LAST,
id DESC
) AS value1,
MAX(value2) KEEP (
DENSE_RANK FIRST
ORDER BY
CASE WHEN value2 IS NOT NULL THEN ts END DESC NULLS LAST,
id DESC
) AS value2,
MAX(value3) KEEP (
DENSE_RANK FIRST
ORDER BY
CASE WHEN value3 IS NOT NULL THEN ts END DESC NULLS LAST,
id DESC
) AS value3,
MAX(value4) KEEP (
DENSE_RANK FIRST
ORDER BY
CASE WHEN value4 IS NOT NULL THEN ts END DESC NULLS LAST,
id DESC
) AS value4,
MAX(value5) KEEP (
DENSE_RANK FIRST
ORDER BY
CASE WHEN value5 IS NOT NULL THEN ts END DESC NULLS LAST,
id DESC
) AS value5,
MAX(value6) KEEP (
DENSE_RANK FIRST
ORDER BY
CASE WHEN value6 IS NOT NULL THEN ts END DESC NULLS LAST,
id DESC
) AS value6
FROM table_name
GROUP BY isin
Which, for the sample data:其中,对于示例数据:
CREATE TABLE table_name ( ts, id, isin, value1, value2, value3, value4, value5, value6 ) AS
SELECT SYSDATE - 5, 1, 1, 'A', 'B', 'C', 'D', 'E', 'F' FROM DUAL UNION ALL
SELECT SYSDATE - 4, 2, 1, NULL, NULL, 'G', NULL, NULL, NULL FROM DUAL UNION ALL
SELECT SYSDATE - 3, 3, 1, NULL, 'H', NULL, NULL, 'I', NULL FROM DUAL UNION ALL
SELECT SYSDATE - 2, 4, 1, NULL, NULL, NULL, 'J', NULL, NULL FROM DUAL UNION ALL
SELECT SYSDATE - 2, 5, 2, 'K', 'L', 'M', 'N', 'O', 'P' FROM DUAL UNION ALL
SELECT SYSDATE - 1, 6, 2, NULL, 'Q', NULL, NULL, NULL, NULL FROM DUAL UNION ALL
SELECT SYSDATE - 0, 7, 2, NULL, NULL, NULL, 'R', NULL, NULL FROM DUAL;
Both output:两者都是 output:
TS |TS | ID |
编号 | ISIN |
伊斯坦布尔 | VALUE1 |
VALUE1 | VALUE2 |
VALUE2 | VALUE3 |
VALUE3 | VALUE4 |
VALUE4 | VALUE5 |
VALUE5 | VALUE6:-------- |
值 6:-------- | -: |
-: | ---: |:----- |:----- |:----- |:----- |:----- |:----- 09-NOV-20 |
---: |:----- |:----- |:----- |:----- |:----- |:----- 11 月 9 日- 20 | 4 |
4 | 1 |
1 | A |
一个 | H |
H | G |
格 | J |
杰| I |
我 | F 11-NOV-20 |
女 20 年 11 月 11 日 | 7 |
7 | 2 |
2 | K |
K | Q |
问 | M |
男| R |
R | O |
欧 | P
P
This is it:就是这个:
SELECT SUBSTR(LISTAGG("col1" ,', ') WITHIN GROUP (ORDER BY "col1"),-1,1)as value1,
SUBSTR(LISTAGG("col2" ,', ') WITHIN GROUP (ORDER BY "col2"),-1,1)as value2,
SUBSTR(LISTAGG("col3" ,', ') WITHIN GROUP (ORDER BY "col3"),-1,1)as value3,
SUBSTR(LISTAGG("col4" ,', ') WITHIN GROUP (ORDER BY "col4"),-1,1)as value4,
SUBSTR(LISTAGG("col5" ,', ') WITHIN GROUP (ORDER BY "col5"),-1,1)as value5,
SUBSTR(LISTAGG("col6" ,', ') WITHIN GROUP (ORDER BY "col6"),-1,1)as value6
FROM Table1
group by "isin";
check: http://sqlfiddle.com/#!4/f02bd/5检查: http://sqlfiddle.com/#!4/f02bd/5
You can use the KEEP clause as follows:您可以按如下方式使用 KEEP 子句:
SELECT ISIN,
MAX(VALUE1) KEEP (DENSE_RANK FIRST ORDER BY CASE WHEN VALUE1 IS NULL THEN NULL ELSE "TIMESTAMP" END DESC NULLS LAST) AS VALUE1,
MAX(VALUE2) KEEP (DENSE_RANK FIRST ORDER BY CASE WHEN VALUE2 IS NULL THEN NULL ELSE "TIMESTAMP" END DESC NULLS LAST) AS VALUE2,
...
FROM YOUR_TABLE
GROUP BY ISIN;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.