如何编写嵌套案例查询并获得正确的结果

时间:2016-09-07 14:25:50

标签: sql oracle oracle11g

我有一个案例查询,需要帮助重新编写它才能获得完美的结果。当前查询如下:

    CASE 
WHEN MonthsRetrieved <= 6 AND MonthsRetrieved > 0 THEN 
    CASE 
        WHEN MonthsSinceLastReceipt <= 6 THEN 'Fast' 
        WHEN MonthsSinceLastReceipt > 6 AND MonthsSinceLastReceipt <= 12 THEN 'Slow' 
        WHEN MonthsSinceLastReceipt > 12 AND MonthsSinceLastReceipt <= 18 THEN 'Very Slow' 
        WHEN MonthsSinceLastReceipt > 18 THEN 'Dead' 
        WHEN OpeningQty = 0 THEN 'New Items' 
        WHEN QtyIssued = 0 THEN 'Non-Moving' 
    ELSE 'Fast' 
    END 
WHEN MonthsRetrieved > 6 AND MonthsRetrieved <= 12 THEN 
    CASE 
        WHEN MonthsRetrieved <= 12 THEN 'Slow' 
        WHEN MonthsSinceLastReceipt > 12 AND MonthsSinceLastReceipt <= 18 THEN 'Very Slow' 
        WHEN MonthsSinceLastReceipt > 18 THEN 'Dead' 
        WHEN OpeningQty = 0 THEN 'New Items' 
        WHEN QtyIssued = 0 THEN 'Non-Moving' 
    ELSE 'Slow' 
    END 
WHEN MonthsRetrieved > 12 AND MonthsRetrieved <= 18 THEN 
    CASE 
        WHEN MonthsSinceLastReceipt <= 18 THEN 'Very Slow' 
        WHEN MonthsSinceLastReceipt > 18 THEN 'Dead' 
        WHEN OpeningQty = 0 THEN 'New Items' 
        WHEN QtyIssued = 0  THEN 'Non-Moving' 
    ELSE 'Very Slow' 
    END 
WHEN MonthsRetrieved = 0 THEN 
    CASE 
        WHEN MonthsSinceLastReceipt = 0 THEN 'Dead' 
        WHEN OpeningQty = 0 THEN 'New Items' 
        WHEN QtyIssued = 0 THEN 'Non-Moving' 
    ELSE 'Dead' 
    END 
WHEN MonthsRetrieved > 18 THEN 
    CASE 
        WHEN MonthsSinceLastReceipt > 18 THEN 'Dead' 
        WHEN OpeningQty = 0 THEN 'New Items' 
        WHEN QtyIssued = 0 THEN 'Non-Moving' 
    ELSE 'Dead' 
    END 
END

我从公式中获得了几个月的值,它位于MonthsRetrieved。 以月为单位的另一个值是MonthsSinceLastReceipt,这是自上次收到日期以来的月份。 OpeningQty是特定日期的开盘数量。 QtyIssued是两个日期之间发布的数量。

这些物品分为快速,慢速,非常慢,死亡,新物品,非移动物品。 case语句是针对每个分类嵌套的。我得到了结果,但他们不正确。我确信我在陈述中忽略了一些事情。

1 个答案:

答案 0 :(得分:1)

案例中的时间按顺序进行评估 一旦评估为真,后面的内容就会被忽略。

所以当你做的时候:

CASE WHEN x >= 1 and x < 3 THEN
   CASE 
   WHEN x = 1 then 'one'
   WHEN x < 3 then 'two'
   WHEN y = 0 then 'THIS GETS NEVER EVALUATED'
   END
END

第3次从未被评估,因为之前的检查肯定是正确的。

因此,您可能需要在OpeningQty和QtyIssued上将这些检查移到MonthsSinceLastReceipt上的检查之上。

还要检查你如何检查MonthsSinceLastReceipt。当前查询中将始终忽略其中一些检查。

我建议只使用这些列名创建一个小的模型表,并用每个案例的值填充它。然后使用该表构造一个包含案例的查询,直到结果完全符合您的预期。

这是一次尝试。但不知道预期的结果应该是什么,这只是猜测。

delete from TestTable;
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(0,0,0,0);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,0,0,0);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,0,0);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,6,19);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,6,13);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,6,7);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,6,3);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,12,19);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,12,13);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,12,7);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,18,19);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,18,15);
insert into TestTable (OpeningQty,QtyIssued,MonthsRetrieved,MonthsSinceLastReceipt) values(1,1,19,0);

select t.*,
CASE
WHEN OpeningQty = 0 THEN 'New Items'
WHEN QtyIssued = 0 THEN 'Non-Moving'
WHEN MonthsRetrieved = 0 THEN 'Dead'
WHEN MonthsRetrieved BETWEEN 1 AND 6 THEN 
    (CASE
     WHEN MonthsSinceLastReceipt > 18 THEN 'Dead'
     WHEN MonthsSinceLastReceipt > 12 THEN 'Very Slow' 
     WHEN MonthsSinceLastReceipt > 6  THEN 'Slow' 
     ELSE 'Fast' 
    END)
WHEN MonthsRetrieved BETWEEN 7 AND 12 THEN 
    (CASE 
     WHEN MonthsSinceLastReceipt > 18 THEN 'Dead'
     WHEN MonthsSinceLastReceipt > 12 THEN 'Very Slow' 
     ELSE 'Slow'
     END)
WHEN MonthsRetrieved BETWEEN 13 AND 18 THEN 
    (CASE 
     WHEN MonthsSinceLastReceipt > 18 THEN 'Dead'
     ELSE 'Very Slow' 
     END)
WHEN MonthsRetrieved >= 19 THEN 'Dead' 
END as result
from TestTable t;