我在 MDX 中对“YYYYMMDD”格式字符串应用日期相关函数时遇到一些问题。例如,如果我在下面有这个查询:
with
member foo as WEEKDay("2013-03-21")
select
foo on 0
from
[Some Cube]
它将在 SSMS 中为 foo 正确输出“5”。但是如果我把第二行改成:
member foo as WEEKDay("20130321")
不幸的是,它会抛出“类型不匹配”错误。
所以我想做的是将字符串转换为某种可识别的日期格式,然后在其上应用函数。任何关于最简单方法的想法,例如使用现有功能?
请注意 该字符串实际上是从运行 MDX 的任何多维数据集中的成员输入的。所以字符串格式可能是可识别的,例如“YYYY-MM-DD”。所以硬编码的字符串转换算法可能不行。
话题太老了,但也许这对某人有帮助。技术相当粗暴,但可扩展。
with
member foo_false as WeekDay("20130321")
member foo_true as WeekDay("2013-03-21")
member foo_brute as
case when IsError(WeekDay("20130321"))=False then WeekDay("20130321") else
case
/* YYYYMMDD */
when
IsError(WeekDay("20130321"))=True AND IsNumeric("20130321")=True
and IsError(WeekDay(Left("20130321",4)+'-'+Right(Left("20130321",6),2)+'-'+Right("20130321",2)))=False
then WeekDay(Left("20130321",4)+'-'+Right(Left("20130321",6),2)+'-'+Right("20130321",2))
/* DDMMYYYY */
when
IsError(WeekDay("20130321"))=True AND IsNumeric("20130321")=True
and IsError(WeekDay(Right("20130321",4)+'-'+Right(Left("20130321",4),2)+'-'+Left("20130321",2)))=False
then WeekDay(Right("20130321",4)+'-'+Right(Left("20130321",4),2)+'-'+Left("20130321",2))
/* MMDDYYYY */
when
IsError(WeekDay("20130321"))=True AND IsNumeric("20130321")=True
and IsError(WeekDay(Right("20130321",4)+'-'+Left("20130321",2)+'-'+Right(Left("20130321",4),2)))=False
then WeekDay(Right("20130321",4)+'-'+Left("20130321",2)+'-'+Right(Left("20130321",4),2))
/* Unsupported Message */
else "Unsupported Format" end
end
select
{foo_false,foo_true,foo_brute} on 0
from
[DATA Cube]
在“Unsupported”之前的末尾添加支持的格式,使用任何输入字符串而不是
"20130321"
.
但是最简单的方法是在插入到 MDX 之前使用另一层(例如 SQL 函数 CONVERT),当然可以。
vba 函数
isDate
可用于检查传递的日期格式是否正确。如果没有,则先使用 dateserial
和 mid
格式化并使用它们。
with
member foo as "20130321"
member bar as
iif(vba!isdate(foo) = TRUE,
WEEKDay(foo), //--if the date is already well formatted, it can be used
WEEKday(vba!dateserial(vba!mid(foo, 0, 4), vba!mid(foo, 5, 2), vba!right(foo, 2))))
select
bar on 0
from
[some cube]
编辑
上面的代码可以修改以适应其他检查,例如
MMDDYYYY
或DDMMYYYY
,但问题是在很多情况下引擎不可能直观地知道传递的值是YYYYMMDDDD
还是DDMMYYYY
或 MMDDYYYY
。以字符串1111111
为例
这可以很容易地采用任何日期格式,因为无论您如何打破它,它都是有效的日期。
我建议你有另一个成员也可以存储日期格式。这样看这个成员,可以解析字符串。
例如
with
member foo as
// "20130321" //YYYYMMDD
// "03212013"//MMDDYYYY
"21032013"//DDMMYYYY
MEMBER dateformat as "ddmmyyyy"
member bar as
iif(vba!isdate(foo) = TRUE,
WEEKDay(foo),
IIF(dateformat = "yyyymmdd", //YYYYMMDD
WEEKday(vba!dateserial(vba!mid(foo, 0, 4), vba!mid(foo, 5, 2), vba!right(foo, 2))),
IIF(dateformat = "mmddyyyy", //MMDDYYYY
WEEKday(vba!dateserial(right(foo, 4), vba!mid(foo, 0, 2), vba!mid(foo, 3, 2))),
IIF(dateformat = "ddmmyyyy", //DDMMYYYY
WEEKday(vba!dateserial(right(foo, 4), vba!mid(foo, 3, 2), vba!mid(foo, 0, 2))),
null
)
)
)
)
select
bar on 0
from
[aw cube]
在这里
FooMember
是一个int,代表一个yyyyMMdd
日期我可以使用下面的代码将它转换为Date
=Format(CDate(Left(CSTR(Fields!FooMember.Value),4)
+ "-" + Mid(CSTR(Fields!FooMember.Value), 5, 2)
+ "-" + Right(CSTR(Fields!FooMember.Value), 2)),
"dd/MM/yyyy")
使用以下代码在立方体中使用它
Format(CDate(Left([Measures].[FooMember],4)
+ "-" + Mid([Measures].[FooMember], 5, 2)
+ "-" + Right([Measures].[FooMember], 2)),"yyyy/MM/dd")
你能帮我把日期字段转换成日时分秒吗? 例如 2023-01-31 00:00:00
SELECT NON EMPTY {[Date].[Day].ALLMEMBERS} ON ROWS, NON EMPTY {[Measures].[SalesQuantity]} ON COLUMNS FROM [V3] WHERE ([Product].[ProductTypeDescription].[Ürün],[Product].[ProductAtt05Desc].&[01])