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 正确。我不认为 NULL 会被当作 FALSE 来处理。如果您必须使用 CASE 语句,我会添加一个 ELSE 子句。也许...
ELSE (1=2)
但由于它永远不会 return 正确,我不确定您要在这里做什么。如果您试图确保您的查询永远不会有 return 个结果,过滤器包含...
1=2
...简单多了。
我在 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 正确。我不认为 NULL 会被当作 FALSE 来处理。如果您必须使用 CASE 语句,我会添加一个 ELSE 子句。也许...
ELSE (1=2)
但由于它永远不会 return 正确,我不确定您要在这里做什么。如果您试图确保您的查询永远不会有 return 个结果,过滤器包含...
1=2
...简单多了。