MDX - 如何根据实际 table 的连续天数来计算维度?
MDX - How to count a dimension based on an existence of sequencial days at fact table?
我需要获取符合两个条件的学生数量:
- 在过去 3 个上课日连续缺勤 3 次,或者
- 最近 2 个月有 5 次无连续缺勤。
我有以下字段的学生每天缺勤的事实:
- 学号
- SchoolCalendarId
- 学号
- ClassId
- QtyAbsents(总为 1,只是求和)
尺寸:
- DimStudent
- DimSchoolCalendar
- DimSchool
- DimClass
我做了一个 MDX return 符合第一个条件的学生姓名:
WITH
MEMBER [A] AS
CASE
WHEN [Measures].[QtyLackingStudents] = 3
THEN 'THREE SEQUENCIAL ABSENTS' ELSE NULL END
SELECT
NON EMPTY { [A] } ON COLUMNS,
NON EMPTY { [DimStudent].[Name].ALLMEMBERS } ON ROWS
FROM
(
SELECT
( FILTER(
[DimSchoolCalendar].[Date].MEMBERS,
[DimSchoolCalendar].[Date].CURRENTMEMBER.NAME = VBAMDX!Format(VBAMDX!Now(),"yyyy-MM-dd")
).ITEM(0).Lag(3):FILTER(
[DimSchoolCalendar].[Date].MEMBERS,
[DimSchoolCalendar].[Date].CURRENTMEMBER.NAME = VBAMDX!Format(VBAMDX!Now(),"yyyy-MM-dd")
).ITEM(0) ) ON COLUMNS
FROM
(
SELECT
( { [DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] } ) ON COLUMNS
FROM [AlunosMatriculados]
)
)
但是我既不能做第二个标准,也不能把所有的东西都放在一个度量中。
编辑:
我做了一个 SQL,return 就是我想要的。我需要 MDX。
SELECT COUNT(DISTINCT f.StudentId)
FROM DW.FactLackingStudents f
INNER JOIN DW.DimSchool e ON e.SchoolId = f.SchoolId
INNER JOIN DW.DimSchoolCalendar ce ON ce.SchoolCalendarId = f.SchoolCalendarId
WHERE (SELECT COUNT(*)
FROM DM.FactLackingStudents f2
INNER JOIN (
SELECT c.SchoolCalendarId
, ROW_NUMBER() OVER(PARTITION BY c.Year, c.SchoolId ORDER BY c.Date DESC) AS Seq
FROM dm.DimCalendarioEscolar c
WHERE c.Year = a.Year
and c.SchoolKey = e.SchoolKey
and c.Date < GETDATE()
and c.SchoolDay = 'IS SCHOOL DAY'
) days ON days.SchoolCalendarId = f2.SchoolCalendarId
and days.Seq <= 3
WHERE f2.StudentId = f.StudentId) = 3 -- ABSENTS AT LAST 3 SCHOOL DAYS IS EQUAL 3
OR
(
SELECT COUNT(*)
FROM DM.FactLackingStudents f2
INNER JOIN (
SELECT c.SchoolCalendarId
, ROW_NUMBER() OVER(PARTITION BY c.Year, c.SchoolId ORDER BY c.Date DESC) AS Seq
FROM dm.DimCalendarioEscolar c
WHERE c.Year = a.Year
and c.SchoolKey = e.SchoolKey
and c.Date BETWEEN DATEADD(DD, -60, GETDATE()) AND GETDATE() -- LAST 2 MONTHS
and c.SchoolDay = 'IS SCHOOL DAY'
) days ON days.SKCalendarioEscolar = f2.SKDataInfrequencia
WHERE f2.StudentId = f.StudentId
) >= 5 -- ABSENTS AT LAST 60 DAYS IS EQUAL 5
一步一步:
第一个条件
创建一个日期集,其中从最开始到今天的所有日期:
{NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')}
使用 IsSchoolDay 交叉加入集合以仅获取上课日:
[DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] * {NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')}
从集合中获取最后三个成员:
Tail(
[DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] * {NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')},
3
)
创建计算量度:
SUM(
Tail(
[DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] * {NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')},
3
),
[Measures].[QtyLackingStudents]
)
第二个条件
获取当前月份:
StrToMember('[DimSchoolCalendar].[Month].&[' + Format(Now(),'yyyy-MM') + ']')
获取最近两个月:
LastPeriods(
2,
StrToMember('[DimSchoolCalendar].[Month].&[' + Format(Now(),'yyyy-MM') + ']')
)
创建计算量度:
SUM(
LastPeriods(
2,
StrToMember('[DimSchoolCalendar].[Month].&[' + Format(Now(),'yyyy-MM') + ']')
),
[Measures].[QtyLackingStudents]
)
最终结果
With
Member [Measures].[1 absent criteria] as
SUM(
Tail(
[DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] * {NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')},
3
),
[Measures].[QtyLackingStudents]
)
Member [Measures].[2 absent criteria] as
SUM(
LastPeriods(
2,
StrToMember('[DimSchoolCalendar].[Month].&[' + Format(Now(),'yyyy-MM') + ']')
),
[Measures].[QtyLackingStudents]
)
Member [Measures].[Absents] as
case
when [Measures].[1 absent criteria] = 3 and [Measures].[2 absent criteria] >= 5
then 'THREE SEQUENCIAL ABSENTS + FIVE ABSENTS LAST 2 MONTHS'
when [Measures].[1 absent criteria] = 3
then 'THREE SEQUENCIAL ABSENTS'
when [Measures].[2 absent criteria] >= 5
then 'FIVE ABSENTS LAST 2 MONTHS'
else NULL
end
Select
{[Measures].[Absents]} on 0,
Non Empty {[DimStudent].[Name].[Name].Members} on 1
From [AlunosMatriculados]
我需要获取符合两个条件的学生数量:
- 在过去 3 个上课日连续缺勤 3 次,或者
- 最近 2 个月有 5 次无连续缺勤。
我有以下字段的学生每天缺勤的事实:
- 学号
- SchoolCalendarId
- 学号
- ClassId
- QtyAbsents(总为 1,只是求和)
尺寸:
- DimStudent
- DimSchoolCalendar
- DimSchool
- DimClass
我做了一个 MDX return 符合第一个条件的学生姓名:
WITH
MEMBER [A] AS
CASE
WHEN [Measures].[QtyLackingStudents] = 3
THEN 'THREE SEQUENCIAL ABSENTS' ELSE NULL END
SELECT
NON EMPTY { [A] } ON COLUMNS,
NON EMPTY { [DimStudent].[Name].ALLMEMBERS } ON ROWS
FROM
(
SELECT
( FILTER(
[DimSchoolCalendar].[Date].MEMBERS,
[DimSchoolCalendar].[Date].CURRENTMEMBER.NAME = VBAMDX!Format(VBAMDX!Now(),"yyyy-MM-dd")
).ITEM(0).Lag(3):FILTER(
[DimSchoolCalendar].[Date].MEMBERS,
[DimSchoolCalendar].[Date].CURRENTMEMBER.NAME = VBAMDX!Format(VBAMDX!Now(),"yyyy-MM-dd")
).ITEM(0) ) ON COLUMNS
FROM
(
SELECT
( { [DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] } ) ON COLUMNS
FROM [AlunosMatriculados]
)
)
但是我既不能做第二个标准,也不能把所有的东西都放在一个度量中。
编辑:
我做了一个 SQL,return 就是我想要的。我需要 MDX。
SELECT COUNT(DISTINCT f.StudentId)
FROM DW.FactLackingStudents f
INNER JOIN DW.DimSchool e ON e.SchoolId = f.SchoolId
INNER JOIN DW.DimSchoolCalendar ce ON ce.SchoolCalendarId = f.SchoolCalendarId
WHERE (SELECT COUNT(*)
FROM DM.FactLackingStudents f2
INNER JOIN (
SELECT c.SchoolCalendarId
, ROW_NUMBER() OVER(PARTITION BY c.Year, c.SchoolId ORDER BY c.Date DESC) AS Seq
FROM dm.DimCalendarioEscolar c
WHERE c.Year = a.Year
and c.SchoolKey = e.SchoolKey
and c.Date < GETDATE()
and c.SchoolDay = 'IS SCHOOL DAY'
) days ON days.SchoolCalendarId = f2.SchoolCalendarId
and days.Seq <= 3
WHERE f2.StudentId = f.StudentId) = 3 -- ABSENTS AT LAST 3 SCHOOL DAYS IS EQUAL 3
OR
(
SELECT COUNT(*)
FROM DM.FactLackingStudents f2
INNER JOIN (
SELECT c.SchoolCalendarId
, ROW_NUMBER() OVER(PARTITION BY c.Year, c.SchoolId ORDER BY c.Date DESC) AS Seq
FROM dm.DimCalendarioEscolar c
WHERE c.Year = a.Year
and c.SchoolKey = e.SchoolKey
and c.Date BETWEEN DATEADD(DD, -60, GETDATE()) AND GETDATE() -- LAST 2 MONTHS
and c.SchoolDay = 'IS SCHOOL DAY'
) days ON days.SKCalendarioEscolar = f2.SKDataInfrequencia
WHERE f2.StudentId = f.StudentId
) >= 5 -- ABSENTS AT LAST 60 DAYS IS EQUAL 5
一步一步:
第一个条件
创建一个日期集,其中从最开始到今天的所有日期:
{NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')}
使用 IsSchoolDay 交叉加入集合以仅获取上课日:
[DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] * {NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')}
从集合中获取最后三个成员:
Tail(
[DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] * {NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')},
3
)
创建计算量度:
SUM(
Tail(
[DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] * {NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')},
3
),
[Measures].[QtyLackingStudents]
)
第二个条件
获取当前月份:
StrToMember('[DimSchoolCalendar].[Month].&[' + Format(Now(),'yyyy-MM') + ']')
获取最近两个月:
LastPeriods(
2,
StrToMember('[DimSchoolCalendar].[Month].&[' + Format(Now(),'yyyy-MM') + ']')
)
创建计算量度:
SUM(
LastPeriods(
2,
StrToMember('[DimSchoolCalendar].[Month].&[' + Format(Now(),'yyyy-MM') + ']')
),
[Measures].[QtyLackingStudents]
)
最终结果
With
Member [Measures].[1 absent criteria] as
SUM(
Tail(
[DimSchoolCalendar].[SchoolDay].&[IsSchoolDay] * {NULL:StrToMember('[DimSchoolCalendar].[Date].&[' + Format(Now(),'yyyy-MM-dd') + ']')},
3
),
[Measures].[QtyLackingStudents]
)
Member [Measures].[2 absent criteria] as
SUM(
LastPeriods(
2,
StrToMember('[DimSchoolCalendar].[Month].&[' + Format(Now(),'yyyy-MM') + ']')
),
[Measures].[QtyLackingStudents]
)
Member [Measures].[Absents] as
case
when [Measures].[1 absent criteria] = 3 and [Measures].[2 absent criteria] >= 5
then 'THREE SEQUENCIAL ABSENTS + FIVE ABSENTS LAST 2 MONTHS'
when [Measures].[1 absent criteria] = 3
then 'THREE SEQUENCIAL ABSENTS'
when [Measures].[2 absent criteria] >= 5
then 'FIVE ABSENTS LAST 2 MONTHS'
else NULL
end
Select
{[Measures].[Absents]} on 0,
Non Empty {[DimStudent].[Name].[Name].Members} on 1
From [AlunosMatriculados]