Oracle SQL - 具有 NULL 值的 max()

Posted

技术标签:

【中文标题】Oracle SQL - 具有 NULL 值的 max()【英文标题】:Oracle SQL - max() with NULL values 【发布时间】:2012-11-16 13:49:38 【问题描述】:

我有一个表,其中包含一系列基于时间的事件,每个事件都有一个开始和结束日期。对于最近(当前)事件,结束日期为 NULL。我试图折叠重复的行,只显示最早的开始日期和最晚的结束日期。由于 NULL 在日期字段中,该行将被忽略。我可以用 NVL() 模拟一个结束日期值,但这会导致前端逻辑搜索并替换该值。

有没有办法让 max() 函数将 NULL 排序为高?

CREATE TABLE CONG_MEMBER_TERM
(
  CONG_MEMBER_TERM_ID  NUMBER(10)               NOT NULL,
  CHAMBER_CD           VARCHAR2(30 BYTE)        NOT NULL,
  CONG_MEMBER_ID       NUMBER(10)               NOT NULL,
  STATE_CD             CHAR(2 BYTE)             NOT NULL,
  DISTRICT             NUMBER(10),
  START_DT             TIMESTAMP(6) WITH TIME ZONE,
  END_DT               TIMESTAMP(6) WITH TIME ZONE
)

此查询有效,但删除结束日期为 NULL 的行。

select CONG_MEMBER_ID, 
       district, 
       min(start_dt), 
       max(end_dt)
  from CONG_MEMBER_TERM
 where CONG_MEMBER_ID = 1716
 group by CONG_MEMBER_ID, district;

这个查询解决了这个问题,但现在我有一个“虚拟”结束日期值(9/9/9999)。我宁愿不必编写代码。

select CONG_MEMBER_ID, 
       district, 
       min(start_dt), 
       max(nvl(end_dt, to_date('9/9/9999', 'mm/dd/yyyy')))
  from CONG_MEMBER_TERM
 where CONG_MEMBER_ID = 1716
 group by CONG_MEMBER_ID, district;

谢谢。

【问题讨论】:

您有很多未接受答案的问题,如果您可以返回并标记答案正确,您将对您的问题更感兴趣(使用左侧的勾号轮廓)回答)。 我什至不知道接受功能。将返回并更新一些较旧的答案。 【参考方案1】:

max(end_dt) keep (dense_rank first order by end_dt desc nulls first)

更新:

SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE t
    (val int, s date, e date)
;

INSERT ALL 
    INTO t (val, s, e)
         VALUES (1, sysdate-3, sysdate-2)
    INTO t (val, s, e)
         VALUES (1, sysdate-2, sysdate-1)
    INTO t (val, s, e)
         VALUES (1, sysdate-1, null)
    INTO t (val, s, e)
         VALUES (2, sysdate-1, sysdate-.5)
    INTO t (val, s, e)
         VALUES (2, sysdate-.5, sysdate-.25)
SELECT * FROM dual
;

查询 1

select val, min(s), max(e) keep (dense_rank first order by e desc nulls first)
from t group by val

Results

| VAL |                          MIN(S) | MAX(E)KEEP(DENSE_RANKFIRSTORDERBYEDESCNULLSFIRST) |
---------------------------------------------------------------------------------------------
|   1 | November, 13 2012 14:15:46+0000 |                                            (null) |
|   2 | November, 15 2012 14:15:46+0000 |                   November, 16 2012 08:15:46+0000 |

【讨论】:

嗯,密集等级。不了解这些分析功能。试一试,看看我能不能让它工作。看起来很有希望。 我需要这种类似的 MS SQL Server 语法...有什么想法吗? 我发现这个解决方案也适用于 Oracle 10g (10.2.0.3.0)。【参考方案2】:
select CONG_MEMBER_ID 
,      district
,      min(start_dt)
,      NULLIF(MAX(NVL(end_dt
                     ,TO_DATE('9999-09-09','YYYY-MM-DD')
                     )
                 )
             ,TO_DATE('9999-09-09','YYYY-MM-DD')
             )
from  CONG_MEMBER_TERM
where CONG_MEMBER_ID = 1716
group by CONG_MEMBER_ID
,        district
;

【讨论】:

虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。

以上是关于Oracle SQL - 具有 NULL 值的 max()的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL - 具有 NULL 值的 max()

SQL从具有空值的行数据中选择MIN值

Sql与oracle中null值的区别

SQL:具有 NULL 值的 AVG

在其中一列中具有多个空值的复合唯一键约束

需要帮助修复 Oracle SQL 查询以返回具有最大列值的行