在Oracle中使用MAX时,如何确保为变量分配null?

时间:2012-06-27 15:01:46

标签: sql oracle variables null

我还有另一个问题涉及Oracle中的Null。

我有一个用作会话表的小表。每行都是特定的会话。 如果会话成功完成,则最后一列指示版本号,如果会话被删除,则为null。

此列可以为null,我想在sessionNumber变量中选择最大版本号或null。 这是我设置的原始

SELECT MAX (VerNumber) INTO sessionNumber
FROM Table_A
WHERE sessionDate = -- some date
AND VerNumber IS NOT NULL;

当col为null时返回一行

我试过像这样使用NVL

SELECT NVL(MAX (VerNumber),NULL) INTO sessionNumber
FROM Table_A
WHERE sessionDate = -- some date
AND VerNumber IS NOT NULL;

为了清除混淆,存在NOT NULL条件以防止同一用户在同一日期进行额外会话。在这种情况下TBH即使删除了NOT NULL条件,我仍然会返回一个(空)行。我认为Nulls和聚合函数都缺少一些东西。

但它不起作用。我也看到了我可以使用异常的地方,但这似乎是一个令人费解的修复。

非常感谢任何指导。

感谢。

按要求进一步澄清。

我的表有四列user,date,state和verNumber

用户和日期是标识符列(不是正式的PK,但你可以这样看待它们。)

状态表示会话是否已完成 verNumber表示该日期的会话已完成的次数,如果该日期的会话未完成,则为null。

我有一个变量sessionNumber,我想分配该日期可用的MAX(VerNumber),或者当日期不可用或VerNumber中的值为null时为null。

表_A

中的示例行
USER    | DATE       | STATE | VERNUMBER
'AName' | 2012-06-25 | 'YES' | 1
'CName' | 2012-06-25 | 'YES' | 2
'BName' | 2012-06-26 | 'NO'  | --NULL

所以对于06-25号日期,我希望2是值 对于06-26我会期望为空。

2 个答案:

答案 0 :(得分:2)

这接近你想要的吗?

http://sqlfiddle.com/#!4/ca465/1

咆哮错误的树?

编辑:忘记最后一个

......这看起来对你来说!!?

http://sqlfiddle.com/#!4/44e50/21

我想也许你想要每个日期都有一个条目,但会话是最后一个(无论用户) - 无论哪种方式,这都会给你一些提示

编辑:这是查询:

http://sqlfiddle.com/#!4/4163d/1

我认为这反映了你的输出!

对于每个人的好处(以及SQL小提琴爆炸!),我做的最后一个查询是:

SELECT Table_A.* FROM 
(
    SELECT
        SessionDate, 
        MAX(CASE WHEN VerNumber IS NULL THEN 'A' ELSE VerNumber END) as Ver
    FROM Table_A
    GROUP BY SessionDate
) TD
INNER JOIN Table_A 
ON NVL(Table_A.VerNumber, 'A') = TD.Ver 
AND Table_A.SessionDate = TD.SessionDate

所以基本上只使用CASE来获取VerNumber列上的表达式的MAX,但使用字母字符来确保MAX选择该列中的NULL。外部查询使用NVL()连接到表达式的内部,这允许将NULL连接到内部查询中的“A”。不确定排序规则是否会导致问题(排序规则是否会改变alpha与数字的排序顺序?)

答案 1 :(得分:1)

如果您在选择中单独使用聚合函数,则总会得到一行。如果您不想返回任何行,则需要添加另一列并使用GROUP BY并对其他列进行过滤,类似于:

SELECT VerNumber, MAX (VerNumber) 
  INTO sessionNumber 
  FROM Table_A 
 WHERE sessionDate = -- some date 
   AND VerNumber IS NOT NULL
 GROUP BY VerNumber; 

我不知道您的数据是如何构建的,因此这可能不是确切的解决方案。我和其他评论过的人一样,对你正在尝试做的事情感到有点困惑。

但请记住,如果你这样做,你将需要一个异常处理程序,因为你将获得一个NO DATA FOUND异常。