【问题标题】:MAX function in oracle not pulling back expected resultsoracle 中的 MAX 函数没有撤回预期结果
【发布时间】:2021-11-16 22:04:25
【问题描述】:

我有一个包含一堆数据的表。数据示例如下:强调文本

DTE UNIQUE_ID ROW_DATA CALL_ROW_ID
8/1/2021 11234 DCNS=FAILED\|HYPO= 1
8/1/2021 11234 DCNS=ACCEPTED \| HYPO=NEW CREDIT 2
8/1/2021 11234 DCNS=FAILED\|HYPO=GIVE ME BIRTHDAY= 4
8/1/2021 11234 DCNS=ACCEPTED\|HYPO=YES 7
8/1/2021 11234 DCNS=CONFIRMED\|HYPO=JULY 25th 2019 10

我有一个查询试图将某些数据堆叠在一行中。查询试图拉回:日期、unique_id,并获取第一个和最后一个 HYPO。

SELECT
    DTE,
    UNIQUE_ID,
    MIN(CASE WHEN HYPO > 0 THEN TRIM(SUBSTR(ROW_DATA, HYPO + 7, INSTR(ROW_DATA, '|', HYPO + 7) - (HYPO + 7))) END ) FIRST_HYPO,
    MAX(CASE WHEN HYPO > 0 THEN TRIM(SUBSTR(ROW_DATA, HYPO + 7, INSTR(ROW_DATA, '|', HYPO + 7) - (HYPO + 7))) END ) LAST_HYPO
FROM
    (SELECT DTE, UNIQUE_ID, ROW_DATA, INSTR(ROW_DATA, '| HYPO=') as HYPO
    FROM
        (SELECT TO_CHAR(DTE, 'MM/DD/YYYY' AS DTE, UNIQUE_ID, '| ' || ROW_DATA || ' |' as ROW_DATA, CALL_ROW_ID
        FROM DATATABLE))

我想要得到的是:

DTE UNIQUE_ID FIRST_HYPO LAST_HYPO
8/1/2021 11234 NEW_CREDIT JULY 25th 2019

但我得到的是

DTE UNIQUE_ID FIRST_HYPO LAST_HYPO
8/1/2021 11234 GIVE ME BIRTHDAY YES

这很奇怪,因为数据是有序的,但 MIN/MAX 选择了不同的行。我尝试在所有级别的查询中执行ORDER BY,但并不能修复结果。它总是拉回相同的字段。

有谁知道如何解决这个问题?

【问题讨论】:

  • 您的查询有语法错误。在TO_CHAR 之后缺少)CALL_DATE 列不存在;它使用聚合列和非聚合列的混合,没有GROUP BY 子句。请edit您的问题,以便它实际运行。此外,您正在匹配| HYPO,但某些数据在|H 之间没有空格。

标签: sql oracle max


【解决方案1】:

'YES'是最大的hypo。它以“Y”开头,因此在字母表中排在最后。假设您的样本数据中有错字,不小心在行中省略了HYPO=,那么“GIVE ME BIRTHDAY”将是最低限度。它以“G”开头,按字母顺序排在第一位。

您说您想要第一个和最后一个低,并希望 Oracle 会神奇地知道您首先考虑和最后考虑的内容,并相应地应用 MIN/MAX。我想您的想法是查看所有带低 (call_row_id 2、7 和 10) 的行,其中首先考虑具有最低 call_row_id 的行,最后考虑具有最大 call_row_id 的行。

您可以使用 Oracle 的 KEEP FIRST/LAST 获得聚合中的第一行和最后一行的值。

select
  dte, unique_id,
  max(hypo) keep (dense_rank first order by nvl2(hypo, 1, 2), call_row_id) as first_hypo,
  max(hypo) keep (dense_rank last  order by nvl2(hypo, 2, 1), call_row_id) as last_hypo
from
(
  select
    dte, unique_id, call_row_id,
    trim(regexp_replace(row_data, '^.*HYPO=(.*)$', '\1')) as hypo
  from datatable
)
group by dte, unique_id
order by dte, unique_id;

演示:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=ab99c199b1c3ce49a2029f0205700e14

【讨论】:

  • GIVE ME BIRTHDAY 不是最小值,因为它没有 | HYPO 前缀。
  • @MT0:确实如此。正如 OP 说他们用 MIN 得到了这个值,我假设样本数据中有错字,忘记在我的回答中提及这一点。
  • 对不起,我之前的例子中的错字。这个答案很好用,谢谢!
猜你喜欢
  • 2018-10-24
  • 2012-05-01
  • 1970-01-01
  • 2016-06-28
  • 2019-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多