olap分析平臺的設計與實現(六)-MDX語句基礎

本章節總結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

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章