繁体   English   中英

Oracle SQL - 获取每列的最新值

[英]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";

检查: http://sqlfiddle.com/#!4/f02bd/5

您可以按如下方式使用 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM