[英]Oracle SQL - Get latest value of each column
假设我有一个看起来像这样的表:
表中有 2 个 ISIN(ISIN 1 和 2)。 如果您查看第一行,您会看到所有字段都填满了值。 在第二行中只有一个字段被填充,代表该字段的更新(所有空字段都没有改变)。
基本上我想要每个字段的最新值(按 ISIN 分组)。
如果有内置的 function 或实现我的结果的简单方法,我正在考虑创建一个物化视图。 如果没有,我将创建一个 pipe 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
或者,您可以使用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
其中,对于示例数据:
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;
两者都是 output:
TS | 编号 | 伊斯坦布尔 | VALUE1 | VALUE2 | VALUE3 | VALUE4 | VALUE5 | 值 6:-------- | -: | ---: |:----- |:----- |:----- |:----- |:----- |:----- 11 月 9 日- 20 | 4 | 1 | 一个 | H | 格 | 杰| 我 | 女 20 年 11 月 11 日 | 7 | 2 | K | 问 | 男| R | 欧 | P
db<> 在这里摆弄
就是这个:
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";
您可以按如下方式使用 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.