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

Cognos Report Studio (case statement) - Syntax error

我在 Cognos Report Studio 中有一个案例陈述,其中如果日期是上一年当月的 1 日,那么它应该获取上一年最后一整月(从 1 到最后一个日期)的数据。我认为这是一个语法错误。下面是我提前sharing.Thanks的代码!如有疑问,请告诉我。

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

对于 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

你的逻辑是正确的。但是,看起来您正在过滤器中使用 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])

==校正==

我注意到我的答案虽然被接受了,但并不完全正确。请参阅下面的说明。

我提供的 CASE WHEN 会产生错误,因为条件引用了因源行而异的波动值。当我构建答案时,我专注于句法问题而不评估逻辑。为了使这种类型的逻辑起作用,CASE WHEN 之后的条件应该为整个查询引用单个值。这可以是 user-supplied 参数或函数或常量 return 为整个查询设置单个值,例如:

(year(current_date) = 2018)

(?param? = 'foo')

下面是一个在10.2下运行的非常简单的例子,可以作为模板使用:

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

同样,我的替代逻辑在形式上是正确的,但在逻辑上是不正确的,因为我又一次没有检查就直接从问题中提取了逻辑。构建的逻辑永远不会 return 为真。修改后的修正版如下:

_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 月等

除了因为 return 为 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 子句,您的原始代码应该 return TRUE 或 NULL。不幸的是,它永远不会 return 正确。我不认为 N​​ULL 会被当作 FALSE 来处理。如果您必须使用 CASE 语句,我会添加一个 ELSE 子句。也许...

ELSE (1=2)

但由于它永远不会 return 正确,我不确定您要在这里做什么。如果您试图确保您的查询永远不会有 return 个结果,过滤器包含...

1=2

...简单多了。