我在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
答案 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
...要简单得多。