我试图理解oracle中的MAX函数,我无法理解当列连接时它是如何工作的。
select max(effdate) from
(
select to_date('30-SEP-2023','DD-MON-YYYY') effdate from dual
union
select to_date('31-DEC-2022','DD-MON-YYYY') EFFDATE from dual
);
结果:符合预期
2023 年 9 月 30 日 00:00:00
查询2:
select max(effdate||' ==== '||amt) from
(
select to_date('30-SEP-2023','DD-MON-YYYY') effdate, 14 amt from dual
union
select to_date('31-DEC-2022','DD-MON-YYYY') EFFDATE, 10 amt from dual
);
结果:
2022 年 12 月 31 日 00:00:00 ==== 10
我预计:2023 年 9 月 30 日 ==== 14
问题3:
select max(effdate||' ==== '||amt) from
(
select to_date('30-SEP-2023','DD-MON-YYYY') effdate, 14 amt from dual
union
select to_date('30-DEC-2022','DD-MON-YYYY') EFFDATE, 10 amt from dual
);
结果:
2023 年 9 月 30 日 00:00:00 ==== 14
有人可以解释一下 MAX() 在这里是如何工作的吗?
将日期与字符串连接后,它会变成字符串,因此,最大值是按字母顺序导出的,而不是基于日期顺序:
这里如何根据日期然后通过 amt 获取最大值:
SELECT effdate || ' ==== ' || amt
FROM (
SELECT to_date('30-SEP-2023','DD-MON-YYYY') effdate, 14 amt FROM dual
UNION
SELECT to_date('31-DEC-2022','DD-MON-YYYY') EFFDATE, 10 amt FROM dual
)
ORDER BY effdate DESC, amt DESC
FETCH FIRST 1 ROWS ONLY
查询 2 有效:
WITH sample_data (effdate, amt) AS (
SELECT DATE '2023-09-30', 14 FROM DUAL UNION ALL
SELECT DATE '2022-12-31', 10 FROM DUAL
)
SELECT MAX(
TO_CHAR(
effdate,
(SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
)
|| ' ==== '
|| TO_CHAR(amt)
) AS maximum
from sample_data;
当您执行从
DATE
到字符串的隐式转换时,Oracle 将使用 TO_CHAR
会话参数的当前值作为日期的格式模型在日期上隐式调用 NLS_DATE_FORMAT
。
如果您使用:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY';
并运行查询,则输出为:
最大 |
---|
2022 年 12 月 31 日 ==== 10 |
由于它将日期格式设置为
31-DEC-2022
和 30-SEP-2023
,并且在比较字符串时 '31'
大于 '30'
,因此它将采用最大字母值(而不是最大日期值)。
如果您使用:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
然后运行完全相同的查询,输出为:
最大 |
---|
2023-09-30 00:00:00 ==== 14 |
隐式格式模型已更改,因此日期组成部分的顺序已更改,并且字符串中字符的字母数字排序顺序对应于日期的顺序,以便您获得预期的输出。
由此得出的结论是:
从 Oracle 12 开始,您可以使用:
WITH sample_data (effdate, amt) AS (
SELECT DATE '2023-09-30', 14 FROM DUAL UNION ALL
SELECT DATE '2022-12-31', 10 FROM DUAL
)
SELECT *
from sample_data
ORDER BY effdate DESC
FETCH FIRST ROW ONLY;
获取最大日期和对应的
amt
。