Cognos Report Studio(案例陈述) - 语法错误

时间:2018-03-04 19:36:36

标签: db2 cognos db2-luw cognos-10 cognos-bi

我在Cognos report studio中有一个案例陈述,其中如果日期是上一年当月的第一天,那么它应该获取上一年的最后一个月(1到最后日期)数据的数据。我认为这是一个语法错误。下面是我正在分享的代码。谢谢!如有疑虑,请通知我。

case when 
[Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD] = _first_of_month(_add_years(current_date,-1))
then 
[Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD] 
  between
_first_of_month(_add_months(_add_years(current_date,-1),-1))
   and
_last_of_month (_add_months(_add_years(current_date,-1),-1))
end

3 个答案:

答案 0 :(得分:1)

你的逻辑是正确的。但是,看起来您在过滤器中使用CASE语句。 Cognos对过滤器中的CASE语法很挑剔。它要求您将条件和结果都放在括号中。试试这个:

case when 
([Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD] = _first_of_month(_add_years(current_date,-1)))
then 
([Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD]
  between
_first_of_month(_add_months(_add_years(current_date,-1),-1))
   and
_last_of_month (_add_months(_add_years(current_date,-1),-1)))
end

这是一个替代语法也应该有效:

extract(year,current_date) - 1 = extract(year, [Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD])
AND 
extract(month,current_date) = extract(month, [Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD])

<强> == CORRECTION ==

我注意到我的回答并不完全正确,即使它被接受了。请参阅下面的说明。

我提供的情况会产生错误,因为条件引用了因源行而异的波动值。当我构建答案时,我专注于语法问题,而没有考虑逻辑。为了使这种类型的逻辑起作用,CASE WHEN之后的条件应该引用整个查询的单个值。这可以是用户提供的参数,也可以是为整个查询返回单个值的函数或常量,例如:

(year(current_date) = 2018)

(?param? = 'foo')

以下是一个非常简单的示例,适用于10.2并可用作模板:

CASE 
WHEN (?param? = 'foo') 
THEN (extract(year,[Date]) = 2018)
ELSE (extract(year,[Date]) = 2017)
END

同样,我的替代逻辑在形式上是正确的,但在逻辑上是不正确的,因为我再次从问题中直接解除了逻辑,没有经过检验。构造的逻辑永远不会返回真实。修改后的更正版本如下:

_first_of_month(current_date) = current_date /* Today is the first day of the month */
AND month(_add_months(current_date,-1)) = month([Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD]) /* The month of the row matches the previous month */
AND year(_add_years(current_date,-1)) = year([Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD]) /* The year of the row matches the previous year */

如果在任何月份的第一天运行,这将为您提供去年所有上个月的数据。如果您在2018年11月1日运行它,您将获得2017年10月整个月的数据。如果您在2018年1月1日运行它,您将获得2016年12月整个月的数据等。

答案 1 :(得分:0)

对于Db2-LUW v10.5,这些谓词可以帮助您构建所需的SQL:

-- Date of the first-day of the current month last year:

date(year(current date - 1 year)||'-'||month(current date)||'-01')

-- Date of the last-day of the current month last year:

date(year(current date - 1 year)||'-'||month(current date+ 1 month)||'-01') - 1 day

答案 2 :(得分:0)

除了由于返回NULL而可能出错的可能性外,(Johnsonium的)代码与此等效:

[Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD] = _first_of_month(_add_years(current_date,-1))
and (
    [Corporate Calendar_BL].[Receive Date Details].[Receive Date - RD] between
        _first_of_month(_add_months(_add_years(current_date,-1),-1)) and
        _last_of_month (_add_months(_add_years(current_date,-1),-1))
    )

没有ELSE子句,原始代码应返回TRUE或NULL。不幸的是,它永远不会返回TRUE。我不认为NULL将被视为FALSE。如果必须使用CASE语句,我将添加一个ELSE子句。也许...

ELSE (1=2)

但是由于它永远不会返回TRUE,所以我不确定您要在这里做什么。如果您要确保查询永远不会返回结果,请使用包含...

的过滤器
1=2

...要简单得多。