OLAP分析(六)-MDX语句基础

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/wh_xia_jun/article/details/90510512

本章节总结MDX语句如下基本内容:

  1. , :
  2. member
  3. children
  4. decendants
  5. non empty
  6. tuple
  7. set
  8. Queries
  9. CrossJoin()
  10. Filter() 
  11. Sort()
  12. 格式化?

写了语句报错:

Caused by: mondrian.olap.MondrianException: Mondrian Error:Syntax error at line 1, column 77, token 'row'

把 on row 修改为 on rows,这个错误消失。

但是,加了Time维度,查询不出数据,先检查数据是否有问题,再考虑是不是MDX要写完全的维度?

数据连接没问题,那就怀疑是要写全部维度:

先用新的维度代替原来的year,下面测试后通过。

  String mdxStr_1 ="select {[Measures].[金额]} on columns,{[Time].[2009],[Time].[2010],[Time].[2011],[Time].[2012]} on rows from [Col_trade_detail] ";

结果: 

 ps:{} 引用某个特定维度、多个维度的一组元素。

     元素名称用[]引用,且不同部分用(.)分割。

2017年前3个季度的非税收入:

       //2017年前三个季度
        String mdxStr_2 ="select {[Measures].[金额]} on columns,{[Time].[2017].[1],[Time].[2017].[2],[Time].[2017].[3]} on rows from [Col_trade_detail] ";
        //2017年前三个季度
        String mdxStr_3 ="select {[Measures].[金额]} on columns,{[Time].[2017].[1]:[Time].[2017].[3]} on rows from [Col_trade_detail] ";

结果:

Member:  我理解就是dimession、hier、level上的member.

这里,我要获取sz县07年到17年的非税收入。

        String mdxStr_4 =
        "SELECT"+
                "{[Time].[Time].[2009], [Time].[Time].[2010], [Time].[Time].[2011], [Time].[Time].[2012], [Time].[Time].[2013], [Time].[Time].[2014], [Time].[Time].[2015], [Time].[Time].[2016], [Time].[Time].[2017]} ON COLUMNS,"
                +"Order({[Account].[Account_L].[其他收入].[其他收入].[房租收入]}, [Measures].[金额], DESC) ON ROWS "
                + "FROM [Col_trade_detail]";

        String mdxStr_5 =
                "SELECT"+
                        "{[Time].[Time].[2009], [Time].[Time].[2010], [Time].[Time].[2011], [Time].[Time].[2012], [Time].[Time].[2013], [Time].[Time].[2014], [Time].[Time].[2015], [Time].[Time].[2016], [Time].[Time].[2017]} ON COLUMNS,"
                        +"Order({[Account].[Account_L].Members}, [Measures].[金额], DESC) ON ROWS "
                        + "FROM [Col_trade_detail]";

        String mdxStr_6 =
                "SELECT"+
                        "{[Time].Members}  ON COLUMNS,"
                        +"{[Account].[Account_L].Members} ON ROWS "
                        + "FROM [Col_trade_detail]";

 结果:

可以看出,Member是这个元数据范围内的所有成员。

returns a set of all members associated with that metadata scope。

ps:Member不会返回计算成员?

可是,我只想看一级的成员,怎么办,该Children上场:

        String mdxStr_7 =
                "SELECT"+
                        "{[Time].[Time].[2008]:[Time].[Time].[2017]}  ON COLUMNS,"
                        +"{[Account].[Account_L].Children} ON ROWS "
                        + "FROM [Col_trade_detail]";

        String mdxStr_8 =
                "SELECT"+
                        "{[Time].[Time].Children}  ON COLUMNS,"
                        +"{[Account].[Account_L].Children} ON ROWS "
                        + "FROM [Col_trade_detail]";

mdxStr_7 结果如下:

可以看出,该县10年间,政府基金收入增长了20倍。

我还需要汇总值,维度中加一个元素:

        String mdxStr_9 =
                "SELECT"+
                        "{[Time].[Time].[2008]:[Time].[Time].[2017]}  ON COLUMNS,"
                        +"{[Account].[Account_L],[Account].[Account_L].Children} ON ROWS "
                        + "FROM [Col_trade_detail]";

 结果如下:

可以看到,出现了All Account行,它是配置文件中

<Hierarchy name='Account_L' allMemberName='All Account' >中设定的。

从上面查询可以得知,该县2017非税收入超过5亿,超过该年该县企业所得税,接近企业增值税。

mdxStr_8 结果如下:

可以看到,Time的childen 只是第一年,Time类型维度的Children和普通维度不一样!

ps:

If you request the children of a leaf-level member, you’ll get an empty set of members back.

Descendants:

我理解:以某个memeber 为基点,获取相关成员。

这里,我想获取某2017年全部月份政府基金及罚没收入的情况,mdx语句如下:

            //年度descendant
        String mdxStr_10 =
                "SELECT"+
                        "{[Account].[Account_L].[政府性基金收入],[Account].[Account_L].[国有资源(资产)有偿使用收入]," +
                        "[Account].[Account_L].[罚没收入]}  ON COLUMNS,"
                        +"Descendants([Time].[Time].[2017],[Time].[Year],SELF) ON ROWS "
                        + "FROM [Col_trade_detail]";
        //Q descendant
        String mdxStr_11 =
                "SELECT"+
                        "{[Account].[Account_L].[政府性基金收入],[Account].[Account_L].[国有资源(资产)有偿使用收入]," +
                        "[Account].[Account_L].[罚没收入]}  ON COLUMNS,"
                        +"Descendants([Time].[Time].[2017],[Time].[Quarter],SELF) ON ROWS "
                        + "FROM [Col_trade_detail]";

        //Q descendant
        String mdxStr_12 =
                "SELECT"+
                        "{[Account].[Account_L].[政府性基金收入],[Account].[Account_L].[国有资源(资产)有偿使用收入]," +
                        "[Account].[Account_L].[罚没收入]}  ON COLUMNS,"
                        +"Descendants([Time].[Time].[2017],[Time].[Quarter],SELF) ON ROWS "
                        + "FROM [Col_trade_detail]";

        //Month descendant
        String mdxStr_13 =
                "SELECT"+
                        "{[Account].[Account_L].[政府性基金收入],[Account].[Account_L].[国有资源(资产)有偿使用收入]," +
                        "[Account].[Account_L].[罚没收入]}  ON COLUMNS,"
                        +"Descendants([Time].[Time].[2017],[Time].[Month],SELF) ON ROWS "
                        + "FROM [Col_trade_detail]";

descendant,作用在年、季度、月份上,月份的结果如下:

以上数据可以看出,政府基金征收,金额最大的月份在12月,国有资源有偿使用征收最大值在10月,罚没收入最大值出现在3月份。 

我曾把decendant中间的参数写成:[Time].[Year].[Quarter],结果直接报错,说是找不到这个,看文档中描述如下:

Descendants() returns the members below member related to the level or generation, with a number of selection options based on the optional flag。

关联的level (层)与generation(世代)。

对Time维度而言:

<Hierarchies>
  <Hierarchy name='Time' hasAll='false'>
    <Level attribute='Year'/>
    <Level attribute='Quarter'/>
    <Level attribute='Month'/>
  </Hierarchy>
</Hierarchies>

层当然是Year、Quarter、Month。

上面,我们只看到月份,我还想知道季度等,修改参数即可。

        String mdxStr_14 =
                "SELECT"+
                        "{[Account].[Account_L].[政府性基金收入],[Account].[Account_L].[国有资源(资产)有偿使用收入]," +
                        "[Account].[Account_L].[罚没收入]}  ON COLUMNS,"
                        +"Descendants([Time].[Time].[2017],[Time].[Month],SELF_AND_BEFORE) ON ROWS "
                        + "FROM [Col_trade_detail]";

 结果如下:

NON EMPTY :

All we need to do is to add the NON EMPTY keywords at the beginning of our request for the axis.

去掉结果当中的空值:

        String mdxStr_15=
                "SELECT"+
                        "{[Time].Members}  ON COLUMNS,"
                        +"non empty{[Account].[Account_L].Members} ON ROWS "
                        + "FROM [Col_trade_detail]";

tuple:

A tuple is a combination of members from one or more dimensions. It is essentially a multidimensional member

tuple本身是个成员,可以是个多维度成员。

tuple用“()”标记。

A tuple can stand for a slice of a cube, where the cube is sliced by each member in the tuple.

set:

A set is simply an ordered collection of tuples

Although sets might be better called “collections” or “sequences,” we are stuck with “set” for now

Syntactically, a set may be specified in a number of ways. Perhaps the most common is to list the tuples within {}.

Every tuple in a set must have the same dimensionality.

可以把set看出元组的集合(tuple),不过,一个set中,元组(tuple)的结构应该是同类型的。

Queries:

An MDX query result is just another cube that is a transformation of the cube that is being queried.

Note that all MDX queries return cells.

CrossJoin() :

In many cases, you will want to take the cross-product of members (or tuples) in two different sets (that is, specify all of their ossible combinations). The CrossJoin() function is the most direct way of combining the two sets in this way.

The syntax is as follows:

CrossJoin (set1, set2)

我理解,返回的还是一个set.

sz县的数据太单薄,后面争取拿个地级市的数据做测试。

这里我先增加一个维度,笔数,即度量分为金额与笔数2个部分。

        String mdxStr_16 =
                "SELECT "+
                        "CrossJoin({[Account].[Account_L].[政府性基金收入],[Account].[Account_L].[国有资源(资产)有偿使用收入]," +
                        "[Account].[Account_L].[罚没收入]}," +
                        "{ [Measures].[金额], [Measures].[笔数] })  ON COLUMNS,"
                        +"Descendants([Time].[Time].[2017],[Time].[Month],SELF) ON ROWS "
                        + "FROM [Col_trade_detail]";

执行结果:

我们原预计2017年,sz县罚没收入笔数会比较多,查询后,发现不是这样的,这就说明罚没收入解缴国库时间,可能有延迟现象?

Filter() :

Filter (set, boolean-expression)

例如,我这里要找出政府基金收入超过一个亿的月份。

       String mdxStr_17 =
                "SELECT "+
                        "CrossJoin({[Account].[Account_L].[政府性基金收入],[Account].[Account_L].[国有资源(资产)有偿使用收入]," +
                        "[Account].[Account_L].[罚没收入]}," +
                        "{ [Measures].[金额], [Measures].[笔数] })  ON COLUMNS,"
                        +"Filter(Descendants([Time].[Time].[2017],[Time].[Month],SELF),[Measures].[金额]>100000000) ON ROWS "
                        + "FROM [Col_trade_detail]";

从结果看出,过亿的月份,在3、4季度。

有必要指出:过滤表达式有可以用元组。这正是MDX强大的地方。

Sort():

To put the tuples in a set into a sequence based on associated data values, we need to use the Order() function.

The syntax for the Order() function is:

Order (set1, expression [, ASC | DESC | BASC | BDESC])

Order() returns a set

我这里想查询2008-002017年全部项目的收入情况排名:

        String mdxStr_18 =
                "SELECT "+
                        "{[Measures].[金额]} ON COLUMNS,"
                        +"{Order([Account].[Account_L].Children,[Measures].[金额],BDESC)} ON ROWS "
                        + "FROM [Col_trade_detail]" +
                        "   where [Time].[Time].[2008]:[Time].[Time].[2017]";

结果如下:

从结果可以看出,该县10年间行政事业收费的收入是国有zh资源有偿使用收入的2倍。总罚没收收入是有偿使用收入的62%。

我想看细致的数据:

        String mdxStr_19 =
                "SELECT "+
                        "{[Measures].[金额]} ON COLUMNS,"
                        +"non empty {Order([Account].Members,[Measures].[金额],BDESC)} ON ROWS "
                        + "FROM [Col_trade_detail]" +
                        "   where [Time].[Time].[2008]:[Time].[Time].[2017]";

结果如下:

可以看出卖地收入是老大。这个一点都不例外吧。10年间,卖地的收入占了非税收入的1/3;17年,土地相关收入更占非税收入62%;但直接卖国有土地17年只占非税收入30%,其余为补充耕地指标交易收入。从非税构成上看,该县房地产发展并不好。

补充耕地指标交易收入能不能看成财政转移支付的一种方式呢,是一种发达地区向经济困难地区扶贫的一种做法?不晓得我理解对否。

排序我们可以有三种方式:

1、根据大类排序,这个mdxStr_18语句就可以;

2、根据大项、明细项目混合排序, mdxStr_19好像做到了

3、还有一种方式,大项排好顺序,大项内的子节点在2级或者n级也排好顺序。(把BDESC 换成DESC即可)

ps:The BDESC variant breaks (that is, ignores) the hierarchy.

结果如图:

项目维度我定义的层级比较多,我只想看前3个级别的排序数据:

 String mdxStr_20 =
                "SELECT "+
                        "{[Measures].[金额]} ON COLUMNS,"
                        +"non empty {Order(Descendants([Account].[政府性基金收入].[其他基金收入].[补充耕地指标交易收入]," +
                        "[Account].[Level3projectname],SELF_AND_BEFORE),[Measures].[金额],DESC)} ON ROWS "
                        + "FROM [Col_trade_detail]" +
                        "   where [Time].[Time].[2017]:[Time].[Time].[2017]";

结果:

Querying Cell Properties: 

我目前的理解是,没有指定的情况下,有三个基本属性吧:一个是结果的序号、一个是原生的值,一个是格式化的值(或者格式)?

问题:

我本意是想看第三层级数据,结果,只有一个分支的内容,这是个问题?先放着。

还有,我只想看第三层级 不显示上面层级内容,也是个问题。

我只想深入到某层,暂时还不会。

DIMENSION PROPERTIES ?不理解,暂时放一下。

格式化:

with member晓得怎么格式化

cell PROPERTIES 好像和格式化有点关系? 

我是在schemal中格式化的:

<Measure name="金额" column="AMT" aggregator="sum" visible="true" formatString="0"/>

上一个章节:olap4j的使用

下一章节:计算成员与命名set

猜你喜欢

转载自blog.csdn.net/wh_xia_jun/article/details/90510512
MDX