0

我有另一个关于 Oracle 中 Nulls 的问题。

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

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

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

当 col 为空时,这将返回一行

我试过像这样使用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 条件,我仍然会返回一个(空)行。我认为 Null 和聚合函数缺少一些东西。

但它不起作用。我还看到了可以在哪里使用异常,但这似乎是一个复杂的修复。

非常感谢任何指导。

谢谢。

根据要求进一步澄清。

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

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

state 指示会话是否已完成 verNumber 指示该日期的会话完成的次数,如果该日期的会话没有完成,则可以为空。

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

Table_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,我希望为空。

4

2 回答 2

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”。不确定排序规则是否会在这里引起问题(排序规则是否会改变字母与数字的排序顺序??)

于 2012-06-27T15:41:28.790 回答
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 异常。

于 2012-06-27T15:43:45.293 回答