Where condition in Mondrian

倖福魔咒の 提交于 2019-12-10 11:02:10

问题


MDX query to find the employee salary more then 5000

select 
    {
      [Measures].[Total Employee],
      [Measures].[Total Salary]
    } on columns,
NON EMPTY 
    {
     (
      [Department].[All Department],
      [Position].[All Position],
      [Employee].[All Employee])
    } on rows
from Salary
where 
      [Measures].[Total Salary]>5000

My schema

<Schema name="Foodmart">
  <Cube name="Salary" visible="true" cache="true" enabled="true">
    <Table name="employee" alias="">
    </Table>
    <Dimension type="StandardDimension" visible="true" foreignKey="department_id" name="Department">
      <Hierarchy name="All Department" visible="true" hasAll="true" allMemberName="All Department" primaryKey="department_id" primaryKeyTable="department">
        <Table name="department">
        </Table>
        <Level name="Dept" visible="true" column="department_description" uniqueMembers="true">
        </Level>
      </Hierarchy>
    </Dimension>
    <Dimension type="StandardDimension" visible="true" foreignKey="position_id" name="Position">
      <Hierarchy name="All Position" visible="false" hasAll="true" allMemberName="All Position" primaryKey="position_id" primaryKeyTable="position">
        <Table name="position">
        </Table>
        <Level name="position" visible="true" table="position" column="position_title" uniqueMembers="false">
        </Level>
      </Hierarchy>
    </Dimension>
    <Dimension type="StandardDimension" visible="true" name="Employee">
      <Hierarchy name="All Employee" visible="true" hasAll="true" allMemberName="All Employee">
        <Table name="employee" alias="">
        </Table>
        <Level name="New Level 0" visible="true" column="full_name" uniqueMembers="false">
        </Level>
      </Hierarchy>
    </Dimension>
    <Measure name="Total Salary" column="salary" aggregator="sum" visible="true">
    </Measure>
    <Measure name="Total Employee" column="employee_id" aggregator="distinct-count" visible="true">
    </Measure>
  </Cube>
</Schema>

回答1:


I know if you're coming from slq it looks ok but the following is wrong:

WHERE
      [Measures].[Total Salary]>5000

You could use the filter function inside the SELECT clause:

SELECT
    {
      [Measures].[Total Employee],
      [Measures].[Total Salary]
    } ON COLUMNS,
NON EMPTY 
    {
     (
      [Department].[All Department],
      [Position].[All Position]
     )
    } ON ROWS
FROM [Salary]
WHERE FILTER(
        [Employee].[All Employee].CHILDREN,
        [Measures].[Total Salary]>5000
      );

The above will be filtering employees whose total salary for all time is greater than 5000.

The filter could go around the complete cross set if you like the following but you'll get a list of all the respective employees returned:

SELECT
    {
      [Measures].[Total Employee],
      [Measures].[Total Salary]
    } ON COLUMNS,
NON EMPTY 
    FILTER(
     {
      (
       [Department].[All Department],
       [Position].[All Position],
       [Employee].[All Employee].CHILDREN
      )
     }
    ,[Measures].[Total Salary]>5000
   ) ON ROWS
FROM [Salary];

Or use a HAVING clause across the whole set - although this is logically different that the above:

SELECT
    {
      [Measures].[Total Employee],
      [Measures].[Total Salary]
    } ON COLUMNS,
NON EMPTY 
       [Department].[All Department]
     * [Position].[All Position],
     * [Employee].[All Employee].CHILDREN
   HAVING [Measures].[Total Salary]>5000 ON ROWS
FROM [Salary];

Edit

You can move the filter to a sub-cube if you still require the [All EmplyeeS] member on ROWS:

SELECT
    {
      [Measures].[Total Employee],
      [Measures].[Total Salary]
    } ON COLUMNS,
NON EMPTY 
      [Department].[All Department]
     *[Position].[All Position]
     *[Employee].[All Employee]
    ON ROWS
FROM 
(
SELECT
    FILTER(
        [Employee].[All Employee].CHILDREN,
        [Measures].[Total Salary]>5000
      ) ON 0
FROM [Salary] 
);



回答2:


I guess you are running into space/memory issues. If so, can you try the code below:

select 
    {
      [Measures].[Total Employee],
      [Measures].[Total Salary]
    } on columns,
NON EMPTY 
    {
     NonEmpty(
              (
               [Department].[All Department] *
               [Position].[All Position] *
               [Employee].[All Employee]
              )
              ,[Measures].[Total Salary]
             )
    } having [Measures].[Total Salary] > 5000 on rows
from Salary

The NonEmpty function will remove the empty tuples while cross join.

EDIT 1 How about now?

with member [Measures].SalGrtrThan5000 
as
IIF
  (
   [Measures].[Total Salary] > 5000, 
   1, 
   NULL
  )

select 
    {
      [Measures].[Total Employee],
      [Measures].[Total Salary]
    } on columns,
NON EMPTY 
    {
     NonEmpty(
              (
               [Department].[All Department] *
               [Position].[All Position] *
               [Employee].[All Employee]
              )
              ,[Measures].SalGrtrThan5000 
             )
    } 
      on rows
from Salary

EDIT, using EXISTS

select 
    {
      [Measures].[Total Employee],
      [Measures].[Total Salary]
    } on columns,
NON EMPTY 
    {
     FILTER
        (
            EXISTS (
                      (
                       [Department].[All Department] *
                       [Position].[All Position] *
                       [Employee].[All Employee]
                      )
              , , "SomeMeasureGroup"
                   ) //EXISTS will remove non-empty tuples this way
        , [Measures].[Total Salary] > 5000
        )//Filters the set
    } 
      on rows
from Salary

Replace "SomeMeasureGroup" with the actual name of measure group to which [Measures].[Total Salary] belongs. There is a cell-by-cell filter but with the use of EXISTS, hopefully it will be faster this time.



来源:https://stackoverflow.com/questions/32110971/where-condition-in-mondrian

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!