zoukankan      html  css  js  c++  java
  • Saiku关于MDX过滤的使用-默认显示最近一周的数据(九)

    Saiku查询设定:Saiku查询数据时,每次都是全量查询的,我们现在需要默认展示近一周的数据。

     

    通过编写使用MDX表达式进行过滤

    通过编写MDX表达式,添加新的指标信息对一周以内的数据进行标识 (其实我也想添加新的维度信息,但是好像不生效,所以就用指标了)

    /** 检测日期的差值,小于7 */
    IIf(DateDiff("d",CDate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name), now())> 7, "yes", "no") 
    
    /** 检测日期差值大于0并且小于7 (显示最近一周的数据) 但是其他年份的相同月份的数据也会显示出来*/
    IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))<=7,
    IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))>=0,"週數據","非週數據"),"非週數據")
    
    //处理不同年份的日期差值问题(固定年份差值为0,表示只判定当年的数据) year(now()) 取的值为2019
    IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))<=7,
    IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))>=0,
    IIF( year(cdate(now())) - year(cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))=0,"週數據","非週數據"),"非週數據"),"非週數據")
    

    其中SaikuUseDate是我自定义的日期维度信息,在schame中的定义如下:

        <Dimension name="SaikuUseDate"  foreignKey="ID" >
                <Hierarchy hasAll="true" primaryKey="ID" allMemberName="SaikuUseDate">
                  <Level name="SaikuUseDate" column="saikuUseDate" type='Date'  uniqueMembers="false" />
                </Hierarchy>
            </Dimension>
    

      

    区分最近一周数据与其他数据最终的MDX表达式语句为:

    IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))<=7,
      IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))>=0,
        IIF( year(cdate(now())) - year(cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))=0,"週數據","非週數據"),
      "非週數據"),
    "非週數據")

    saiku中添加新的指标信息如下:

     

    根据新指标信息查询结果如下:

    数据已筛选好了,接下来只需要把 新指标  週數據 字段按照 週數據 與 非週數據 进行筛选就可以啦。

    (目前因为saiku是社区版的,过滤不起作用所以没法演示了,后期如果解决了过滤问题会更新的)

     

    =============更新关于过滤===================终于把过滤问题处理好了============== start

    >>>>>>首先我们学习一下MDX语句进行数据过滤:

    1.登录saiku,选中指定cube

    2. 选择上方的工具栏中的 MDX模式  (表示根据MDX语句查询数据,直接将MDX语句写好然后点击 执行按钮 去执行就可以了【有个问题就是好像MDX模式无法切换到普通的拖拽模式】)

    3. MDX表达式语句如下: (目的:根据日期筛选出近一周的数据)

    语句1:

    WITH
    MEMBER [Measures].[周数据筛选] AS
      IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))<=7 
      AND datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))>=0 
      AND year(cdate(now())) - year(cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))=0,"週數據","非週數據")

    SET [~ROWS] AS {FILTER([SaikuUseDate].[SaikuUseDate].[SaikuUseDate].Members,[Measures].[周数据筛选]="週數據")}
    SELECT
    NON EMPTY {[Measures].[周数据筛选], [Measures].[daycount]} ON COLUMNS,
    NON EMPTY [~ROWS] ON ROWS
    FROM [rs_nbjc_1_1]

    或使用如下MDX表达式进行过滤(这两条语句的结果一样,但是第二条语句将过滤表达式作为条件放入where后面,使得查询的效率提高  推荐使用语句2

    语句2:

    WITH
    SET [~filterByDate] AS
    	 Filter({[SaikuUseDate].[SaikuUseDate].[SaikuUseDate].Members}, 
    		Instr(IIF(datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))<=7 AND 
    		  datediff("y",cdate(now()),cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))>=0 AND 
    		  year(cdate(now())) - year(cdate([SaikuUseDate].[SaikuUseDate].CurrentMember.Name))=0,"yes","no"),"yes") > 0)
    
    SET [~ROWS] AS {[countdate].[countdate].[countdate].Members}
    SELECT
    NON EMPTY { [Measures].[daycount]} ON COLUMNS,
    NON EMPTY [~ROWS] ON ROWS
    FROM [rs_nbjc_1_1]
    where [~filterByDate]

    schame文件中 cube名为  rs_nbjc_1_1  的设计如下:

    <!-- rs_nbjc_1_1 用來做MDX FILTER表達式的測試 -->
        <Cube name="rs_nbjc_1_1">
             
    	<Table name="rs_nbjc_1_1" />
          <Dimension name="SEQID" foreignKey="ID" >
            <Hierarchy hasAll="true" primaryKey="ID" allMemberName="SEQID" >
              <Level name="SEQID" column="ID" uniqueMembers="true" type="String" />
            </Hierarchy>
          </Dimension>
    
    	
    	<Dimension name="countdate"  foreignKey="ID" >
                <Hierarchy hasAll="true" primaryKey="ID" allMemberName="countdate">
                  <Level name="countdate" column="countdate" type='Date'  uniqueMembers="false"  />
                </Hierarchy>
            </Dimension>
    		
    	<Dimension name="SaikuUseDate"  foreignKey="ID" >
                <Hierarchy hasAll="true" primaryKey="ID" allMemberName="SaikuUseDate">
                  <Level name="SaikuUseDate" column="saikuUseDate" type='Date'  uniqueMembers="false" />
                </Hierarchy>
            </Dimension>
    		
            <Measure name="daycount" column="daycount"  aggregator="sum" />
             
        </Cube>
    

      

    >>>>>>使用SAIKU的MDX表达式过滤

    1. 过滤的使用与日常拖拉数据一样,但是记得将需要过滤的字段放入过滤栏位

    2. 在过滤这个位置 左击鼠标,然后依次选中 过滤  >>>  Custom

    3.进入编写MDX过滤表达式弹窗

     过滤表达式内容如下:

    Instr(
    IIF(datediff("y",cdate(now()),cdate([countdate].[countdate].CurrentMember.Name))<=7 
    AND datediff("y",cdate(now()),cdate([countdate].[countdate].CurrentMember.Name))>=0 
    AND year(cdate(now())) - year(cdate([countdate].[countdate].CurrentMember.Name))=0,"yes","no"),"yes")>0
    

    4. 点击ok后,如果取消了自动查询就手动点击一下查询按钮,执行查询后可看到如下结果:(结果数据以及被过滤,取的是近一周的数据,当前日期为 2019-02-28)

    ps:  在这里笔者遇到了一个很神奇的问题,在本地部署的Saiku中使用CDate函数没有任何问题,但是部署到服务器上使用CDate函数时,抛出异常:

    #ERR: mondrian.olap.fun.MondrianEvaluationException: mondrian.olap.InvalidArgumentException: Mondrian Error:Invalid parameter. expression parameter of CDate function must be formatted correctly (2016-05-21)
    

    解决方案:  不使用CDate函数了,使用DateSerial函数将数据转为Date类型

    转换将String类型的日期数据转换为Date日期类型示例:

    CDate:   CDate([countdate].[countdate].CurrentMember.name)

    DateSerial:    DateSerial(cast(left([countdate].[countdate].CurrentMember.name,4) as Integer),cast(mid([countdate].[countdate].CurrentMember.name,6,2) as Integer),cast(mid([countdate].[countdate].CurrentMember.name,9,2) as Integer)) 

    过滤表达式内容如下:

    Instr(
    IIF(datediff("y",cdate(now()),DateSerial(cast(left([countdate].[countdate].CurrentMember.name,4) as Integer),
    			cast(mid([countdate].[countdate].CurrentMember.name,6,2) as Integer),
    			cast(mid([countdate].[countdate].CurrentMember.name,9,2) as Integer))  
    		   )<7
    AND datediff("y",cdate(now()),DateSerial(cast(left([countdate].[countdate].CurrentMember.name,4) as Integer),
    			cast(mid([countdate].[countdate].CurrentMember.name,6,2) as Integer),
    			cast(mid([countdate].[countdate].CurrentMember.name,9,2) as Integer))  
    		   )>=0 
    AND year(cdate(now())) - cast(left([countdate].[countdate].CurrentMember.name,4) as Integer)=0,"yes","no"),"yes")>0

     

    关于过滤二次更新了

    1.过滤出上个月的完整数据,以及当前月的月数据(特殊情况下考虑跨年的数据,当前月份为1月时需要特殊处理)

    展示需求:默认展示上一个月完整数据以及当前月的月数据 (起始日期:上个月的第一天,结束日期: 当前天)

    处理逻辑: 判断当前月是否为1月,如果是1月则特殊处理:取出去年12月份的数据,然后再加上本年1月出现的所有数据。

          如果不是1月,则用当前日期减去一个月,取上个月的第一天作为起始日期,然后当前日期作为结束日期,作比较即可(保证年份相同)。

    IIF(
     month(now())-1 = 0
     , (
    	datediff('y',dateserial(year(now())-1,12,01) , DateSerial(cast(left([countdate].[countdate].CurrentMember.name,4) as Integer) ,
    			cast(mid([countdate].[countdate].CurrentMember.name,6,2) as Integer),
    			cast(mid([countdate].[countdate].CurrentMember.name,9,2) as Integer)))<0
    	and  year(now())-1 - cast(left([countdate].[countdate].CurrentMember.name,4) as Integer) =0
    	)
    		or
    	(
    	datediff("y" ,DateSerial(cast(left([countdate].[countdate].CurrentMember.name,4) as Integer),
    			cast(mid([countdate].[countdate].CurrentMember.name,6,2) as Integer),
    			cast(mid([countdate].[countdate].CurrentMember.name,9,2) as Integer)),now()) <=0	
    		and
    	year(now()) - cast(left([countdate].[countdate].CurrentMember.name,4) as Integer)=0
    	)
     , 	
    	(
    	datediff("y" ,DateSerial(year(now()),month(now())-1,01) ,DateSerial(cast(left([countdate].[countdate].CurrentMember.name,4) as Integer),
    		cast(mid([countdate].[countdate].CurrentMember.name,6,2) as Integer),
    		cast(mid([countdate].[countdate].CurrentMember.name,9,2) as Integer))) <= 0 
    	and
    	datediff("y" ,DateSerial(cast(left([countdate].[countdate].CurrentMember.name,4) as Integer),
    		cast(mid([countdate].[countdate].CurrentMember.name,6,2) as Integer),
    		cast(mid([countdate].[countdate].CurrentMember.name,9,2) as Integer)), now()) <=0	
    	and
    	year(cdate(now())) - cast(left([countdate].[countdate].CurrentMember.name,4) as Integer)=0
    	)
     )
    

      

    2.过滤周数据:展示本周的所有数据 (注意跨年份的周数据)

    展示需求:默认展示最近的周一到目前的所有数据

    处理逻辑:

      先取出所有数据中与当前日期相同的周的数据

      控制取出的数据是本年的或者是上一年12月份的数据

    Datepart('ww',now()) = Datepart('ww',
    		DateSerial(cast(left([saikuUseDate].[saikuUseDate].CurrentMember.name,4) as Integer),
    			cast(mid([saikuUseDate].[saikuUseDate].CurrentMember.name,6,2) as Integer),
    			cast(mid([saikuUseDate].[saikuUseDate].CurrentMember.name,9,2) as Integer)))
    and (
    	(year(now()) = cast(left([saikuUseDate].[saikuUseDate].CurrentMember.name,4) as Integer)) 
    	 or
    	((year(now()) - cast(left([saikuUseDate].[saikuUseDate].CurrentMember.name,4) as Integer)=1))
    	)
    	
    and 
    instr(
    	IIF(cast(left([saikuUseDate].[saikuUseDate].CurrentMember.name,4) as Integer) = (YEAR(now())-1)
    		,(
    			iif((datediff('y',DateSerial(cast(left([saikuUseDate].[saikuUseDate].CurrentMember.name,4) as Integer),
    						cast(mid([saikuUseDate].[saikuUseDate].CurrentMember.name,6,2) as Integer),
    						cast(mid([saikuUseDate].[saikuUseDate].CurrentMember.name,9,2) as Integer)),
    					Dateserial(year(now())-1,12,01))>0)
    				and (cast(left([saikuUseDate].[saikuUseDate].CurrentMember.name,4) as Integer) =(YEAR(now())-1)) 
    			,"yes","no")
    		 )
    	   ,"yes"
    	),"yes")>0

    =============更新关于过滤===================终于把过滤问题处理好了============== end

    ps: 使用过滤表达式后,记得先取消saiku的自动执行哦,然后将用到的数据信息都拖拽好,过滤信息也编写好,最后在手动点击执行!!!(不然每拖拽一次都要执行一遍,很比较浪费内存哦。)

  • 相关阅读:
    asList和subList的缺陷
    oracle和mysql的拼接查询
    Google Guava的splitter用法
    docker创建mongodb并且测试代码
    GitHub 近两万Star,无需编码,可一键生成前后端代码,这个开源项目JeecgBoot有点强
    在深圳养一个娃需要多少钱?2020深圳养娃开销(Excel文本)清单公布!家长直呼扎心了!
    Win7安装AD域管理工具-Win7安装AD域远程服务器管理工具
    盘点2020年那些大厂网盘小厂网盘其他网络存储设备
    完美解决远程计算机需要网络级别身份验证RDO
    OPPO手机的指令合集(工程模式、串号等)
  • 原文地址:https://www.cnblogs.com/DFX339/p/10449839.html
Copyright © 2011-2022 走看看