The following examples should be executed in the schema editor of a dictionary.

1 Basic Example

The section below describes the data model which corresponds to the following schema:

Below is an example of how to define a basic schema with XML:

Copy
<Schema name="SampleData">	
    <Dimension name="Region">
       <Hierarchy hasAll="true" allMemberName="All Regions">
         <Table name="P_QUADRANT_ACTUALS"/>
           <Level name="Region" column="REGION" uniqueMembers="true"/>
       </Hierarchy>
    </Dimension>
    <Dimension name="Department">
       <Hierarchy hasAll="true" allMemberName="All Departments">
         <Table name="P_QUADRANT_ACTUALS"/>
           <Level name="Department" column="DEPARTMENT" uniqueMembers="true"/>
       </Hierarchy>
    </Dimension>
    <Dimension name="Positions">
       <Hierarchy hasAll="true" allMemberName="All Positions">
         <Table name="P_QUADRANT_ACTUALS"/>
           <Level name="Positions" column="POSITIONTITLE" uniqueMembers="true"/>
       </Hierarchy>
    </Dimension>
    <Cube name="Quadrant Analysis">
        <Table name="P_QUADRANT_ACTUALS"/>
        <DimensionUsage name="Region" source="Region"/>
        <DimensionUsage name="Department" source="Department" />
        <DimensionUsage name="Positions" source="Positions" />
        <Measure name="Actual" column="ACTUAL" aggregator="sum" formatString="#,###.00"/>
        <Measure name="Budget" column="BUDGET" aggregator="sum" formatString="#,###.00"/>
        <Measure name="Variance" column="VARIANCE" aggregator="sum" formatString="#,###.00"/>		
    </Cube>
 </Schema>

This schema contains a single cube called Quadrant Analysis. The cube contains three dimensions:

  1. Region
  2. Department
  3. Position
It also contains three measures:
  1. Actual
  2. Budget
  3. Variance

Each measure has a name, a column in the source table, and an aggregator. The aggregator is typically sum, but count, min, max, avg, and distinct-count are also permitted. The distinct-count aggregator has certain limitations if the cube contains parent-child hierarchies.

The data type attribute may have the following values: String, Integer, Numeric, Boolean, Date, Time, and Timestamp. The default value is Numeric, except for count and distinct-count aggregators, which fall under Integer.

An optional attribute may be used to specify how the value will display. For example, users may not want sales units to include decimals, or may want only two decimal places to be shown.

Let's imagine that a user set the dimension "Region" with a simple hierarchy consisting of a single Region level. The dimension's values would be extracted from the Region column of the source table, and the equivalent for the other two dimensions for the cube.

From this application, the following analytical cube can be generated:

2 Simple Example

Below is an example of how to define a simple schema with XML:

Copy
<?xml version="1.0"?>
<Schema name="VentasFinancieras">

        <Dimension name="Empresa" >
			<Hierarchy hasAll="true" allMemberName="Todas las empresas" primaryKey="empcode">
			    <Table name="cempresa"/>
			    <Level name="Código empresa" table="cvenfach" column="empcode" uniqueMembers="false" />
			    <Level name="Nombre empresa" column="empname" uniqueMembers="true" />
			    <Level name="Estado empresa" table="cempresa" column="estado" uniqueMembers="true" />     
			</Hierarchy>
		</Dimension>

		<Dimension name="Proyecto" >
		    <Hierarchy hasAll="true" allMemberName="Todos los proyectos" primaryKey="codigo">
		        <Table name="cproyect"/>
		        <Level name="Código proyecto" table="cvenfach" column="proyec" uniqueMembers="false"/>
		        <Level name="Nombre proyecto" column="nompro" uniqueMembers="true"/>
		        <Level name="Estado proyecto" column="estado" uniqueMembers="true"/>               
		    </Hierarchy>
		</Dimension>

		<Dimension name="Sección" >
		    <Hierarchy hasAll="true" allMemberName="Todas las secciones" primaryKey="codigo">
		        <Table name="cseccion"/>
		        <Level name="Código sección" table="cvenfach" column="seccio" uniqueMembers="false"/>
		        <Level name="Nombre sección" column="nomsec" uniqueMembers="true"/>
		        <Level name="Estado sección" column="estado" uniqueMembers="true"/>
		    </Hierarchy>
		</Dimension>

		<Dimension name="Tercero" >
		    <Hierarchy hasAll="true" allMemberName="Todos los terceros" primaryKey="codigo">
		        <Table name="ctercero"/>
		        <Level name="Código tercero" table="cvenfach" column="tercer" uniqueMembers="false"/>
		        <Level name="Nombre tercero" column="nombre" uniqueMembers="true"/>
		        <Level name="Código perceptor" table="cvenfach" column="tercer" uniqueMembers="false"/>
		        <Level name="Nombre perceptor" column="nombre" uniqueMembers="true"/>
		        <Level name="Código Representante" table="cvenfach" column="tercer" uniqueMembers="false"/>
		        <Level name="Nombre Representante" column="nombre" uniqueMembers="true"/>
		    </Hierarchy>
		</Dimension>

		<Dimension name="Fecha" >
		    <Hierarchy hasAll="true" allMemberName="Fecha" primaryKey="fecfac">
		        <Level name="Fecha" column="fecfac" uniqueMembers="true"/>
		    </Hierarchy>
		</Dimension>		

		<Dimension name="Moneda" >
		    <Hierarchy hasAll="true" allMemberName="Todos las monedas" primaryKey="codigo">
		        <Table name="cmonedas"/>
		        <Level name="Moneda" table="cvenfach" column="codigo" uniqueMembers="false"/>
		        <Level name="Nombre moneda" column="desmon" uniqueMembers="true"/>
		    </Hierarchy>
		</Dimension>

        <Dimension name="Cuenta Financiera" >
		    <Hierarchy hasAll="true" allMemberName="Todas las cuentas financieras" primaryKey="ctafin">
		        <Table name="cbancpro"/>
		        <Level name="Cuenta financiera" table="cvenfach" column="ctafin" uniqueMembers="false"/>
		        <Level name="Nombre Cuenta Financiera" column="nomcta" uniqueMembers="true"/>
		    </Hierarchy>
		</Dimension>


    <Cube name="Ventas" visible="true" cache="true" enabled="true" useLeftJoins="true">
    	<Table name="cvenfach" />

    	<DimensionUsage name= 'Empresa'              source = 'Empresa'              foreignKey="empcode"   />
    	<DimensionUsage name= 'Proyecto'             source = 'Proyecto'             foreignKey="proyec"    />
    	<DimensionUsage name= 'Sección'              source = 'Sección'              foreignKey="seccio"    />
    	<DimensionUsage name= 'Tercero'              source = 'Tercero'              foreignKey="tercer"    />
    	<DimensionUsage name= 'Fecha'                source = 'Fecha'                foreignKey="fecfac"    />
    	<DimensionUsage name= 'Moneda'               source = 'Moneda'               foreignKey="moneda"    />
    	<DimensionUsage name= 'Cuenta Financiera'    source = 'Cuenta Financiera'    foreignKey="ctafin"    />


 		<Measure name="Importe Neto"   		column="impnet"  aggregator="sum" formatString="#,###.00"/>
 		<Measure name="Importe Total"   	column="imptot"  aggregator="sum" formatString="#,###.00"/>
 		<Measure name="Descuento General"   column="dtocab"  aggregator="avg" formatString="#,###.00"/>

 	</Cube>


 	<Cube name="Líneas de Ventas" visible="true" cache="true" enabled="true" useLeftJoins="true">

 	    <Join leftKey='facidx' rightKey='facidx'>
 	        <Table name="cvenfacl" />
            <Table name="cvenfach" />
        </Join>
    
        <DimensionUsage name= 'Empresa'              source = 'Empresa'               foreignKey="cvenfach.empcode"      />
        <DimensionUsage name= 'Proyecto'             source = 'Proyecto'              foreignKey="cvenfach.proyec"       />
        <DimensionUsage name= 'Sección'              source = 'Sección'               foreignKey="cvenfach.seccio"       />
        <DimensionUsage name= 'Tercero'              source = 'Tercero'               foreignKey="cvenfach.tercer"       />
        <DimensionUsage name= 'Fecha'                source = 'Fecha'                 foreignKey="cvenfach.fecfac"       />
        <DimensionUsage name= 'Moneda'               source = 'Moneda'                foreignKey="cvenfach.moneda"       />
        <DimensionUsage name= 'Cuenta Financiera'    source = 'Cuenta Financiera'     foreignKey="cvenfach.ctafin"       />

    	<Measure name="Cantidad"   column="cantid"  aggregator="sum" formatString="#,###.00"/>
    	<Measure name="Precio"     column="precio"  aggregator="sum" formatString="#,###.00"/>

    </Cube>


</Schema>

This schema contains a two cubes called Ventas and Líneas de ventas.

Both cubes contain seven dimensions: Empresa, Proyecto, Seccion, Tercero, Fecha, Moneda and Cuenta financiera.

The cube Ventas contains contains three measures: Importe Neto, Importe Total y Descuento general. The cube Líneas de ventas contains two measures: Cantidad and Precio.

Each measure has a name, a column in the source tables, and an aggregator.

The cube Ventas obtains data from one table named cvenfach By the contrary, the cube named Líneas de ventas obtains data from the join of two tables: cvenfacl and cvenfach. The field facidx is the cabid that relates the items of both tables.

From this application, the following analytical cube can be generated:

3 Normal Example

Although this example has been buit using the ordinary clause JOIN to combine more than two tables, it is highly recommended to built those more complex schemes (more than two tables) using a view table. For further information see section Example: schema defined by a view table.

The data model corresponding to the next example schema is below:

Below is an example of how a more complex schema can be defined with XML:

Copy
<Schema name="SteelWheels">
	<Cube name="SteelWheelsSales" cache="true" enabled="true">
 		<Table name="P_ORDERFACT"/>
 		<Dimension foreignKey="CUSTOMERNUMBER" name="Markets">
 			<Hierarchy hasAll="true" allMemberName="All Markets" primaryKey="CUSTOMERNUMBER" primaryKeyTable="">
 				<Table name="P_CUSTOMER_W_TER"/>
 				<Level name="Territory" column="TERRITORY" type="String" uniqueMembers="true" levelType="Regular" hideMemberIf="Never"></Level>
 				<Level name="Country" column="COUNTRY" type="String" uniqueMembers="true" levelType="Regular" hideMemberIf="Never">
 					<Annotations>
 						<Annotation name="Data.Role">Geography</Annotation>
 						<Annotation name="Geo.Role">country</Annotation>
 					</Annotations>
 				</Level>
 				<Level name="State Province" column="STATE" type="String" uniqueMembers="true" levelType="Regular" hideMemberIf="Never">
 					<Annotations>
 						<Annotation name="Data.Role">Geography</Annotation>
 						<Annotation name="Geo.Role">state</Annotation>
 						<Annotation name="Geo.RequiredParents">country</Annotation>
 					</Annotations>
 				</Level>
 				<Level name="City" column="CITY" type="String" uniqueMembers="true" levelType="Regular" hideMemberIf="Never">
 					<Annotations>
 						<Annotation name="Data.Role">Geography</Annotation>
 						<Annotation name="Geo.Role">city</Annotation>
 						<Annotation name="Geo.RequiredParents">country,state</Annotation>
 					</Annotations>
 				</Level>
 			</Hierarchy>
 		</Dimension>
 		<Dimension foreignKey="CUSTOMERNUMBER" name="Customers">
 			<Hierarchy hasAll="true" allMemberName="All Customers" primaryKey="CUSTOMERNUMBER">
 				<Table name="P_CUSTOMER_W_TER"/>
 				<Level name="Customer" column="CUSTOMERNAME" type="String" uniqueMembers="true" levelType="Regular" hideMemberIf="Never">
 					<Property name="Customer Number" column="CUSTOMERNUMBER" type="Numeric"/>
 					<Property name="Contact First Name" column="CONTACTFIRSTNAME" type="String"/>
 					<Property name="Contact Last Name" column="CONTACTLASTNAME" type="String"/>
 					<Property name="Phone" column="PHONE" type="String"/>
 					<Property name="Address" column="ADDRESSLINE1" type="String"/>
 					<Property name="Credit Limit" column="CREDITLIMIT" type="Numeric"/>
 				</Level>
 			</Hierarchy>
 		</Dimension>
 		<Dimension foreignKey="PRODUCTCODE" name="Product">
 			<Hierarchy name="" hasAll="true" allMemberName="All Products" primaryKey="PRODUCTCODE" primaryKeyTable="P_PRODUCTS" caption="">
 				<Table name="P_PRODUCTS"/>
 				<Level name="Line" table="P_PRODUCTS" column="PRODUCTLINE" type="String" uniqueMembers="false" levelType="Regular" hideMemberIf="Never"></Level>
 				<Level name="Vendor" table="P_PRODUCTS" column="PRODUCTVENDOR" type="String" uniqueMembers="false" levelType="Regular" hideMemberIf="Never"></Level>
 				<Level name="Product" table="P_PRODUCTS" column="PRODUCTNAME" type="String" uniqueMembers="true" levelType="Regular" hideMemberIf="Never">
 					<Property name="Code" column="PRODUCTCODE" type="String"/>
 					<Property name="Vendor" column="PRODUCTVENDOR" type="String"/>
 					<Property name="Description" column="PRODUCTDESCRIPTION" type="String"/>
 				</Level>
 			</Hierarchy>
 		</Dimension>
 		<Dimension type="TimeDimension" foreignKey="TIME_ID" name="Time">
 			<Hierarchy hasAll="true" allMemberName="All Years" primaryKey="TIME_ID">
 				<Table name="P_DIM_TIME"/>
 				<Level name="Years" column="YEAR_ID" type="String" uniqueMembers="true" levelType="TimeYears" hideMemberIf="Never">
 					<Annotations>
 						<Annotation name="AnalyzerDateFormat">[yyyy]</Annotation>
 					</Annotations>
 				</Level>
 				<Level name="Quarters" column="QTR_NAME" ordinalColumn="QTR_ID" type="String" uniqueMembers="false" levelType="TimeQuarters" hideMemberIf="Never">
 					<Annotations>
 						<Annotation name="AnalyzerDateFormat">[yyyy].['QTR'q]</Annotation>
 					</Annotations>
 				</Level>
 				<Level name="Months" column="MONTH_NAME" ordinalColumn="MONTH_ID" type="String" uniqueMembers="false" levelType="TimeMonths" hideMemberIf="Never">
 					<Annotations>
 						<Annotation name="AnalyzerDateFormat">[yyyy].['QTR'q].[MMM]</Annotation>
 					</Annotations>
 				</Level>
 			</Hierarchy>
 		</Dimension>
 		<Dimension foreignKey="STATUS" name="Order Status">
 			<Hierarchy hasAll="true" allMemberName="All Status Types" primaryKey="STATUS">
 				<Level name="Type" column="STATUS" type="String" uniqueMembers="true" levelType="Regular" hideMemberIf="Never"></Level>
 			</Hierarchy>
 		</Dimension>
 		<Measure name="Quantity" column="QUANTITYORDERED" formatString="#,###" aggregator="sum">
 			<Annotations>
 				<Annotation name="AnalyzerBusinessGroup">Measures</Annotation>
 			</Annotations>
 		</Measure>
 		<Measure name="Sales" column="TOTALPRICE" formatString="#,###" aggregator="sum">
 			<Annotations>
 				<Annotation name="AnalyzerBusinessGroup">Measures</Annotation>
 			</Annotations>
 		</Measure>
	</Cube>
</Schema>

As opposed to the previous example:

  • Multiple source tables are combined.
  • Some dimensions open multiple levels: The dimension Markets contains a simple hierarchy with multiple levels: Territory, Country, State/Province, and City.
  • Some dimensions also contain levels with hierarchical relationships. The dimension Time contains three levels with parent-child relationships: Years, Quarters, and Months.
  • By applying the above, the following analytical cube is generated:

4 Complete Example

Although this example has been buit using the ordinary clause JOIN to combine more than two tables, it is highly recommended to built those more complex schemes (more than two tables) using a view table. For further information see section Example: schema defined by a view table.

The data model which corresponds to the next schema is below:

Below is an example of how a more complex schema can be defined with XML:

Copy
<?xml version="1.0"?>
<Schema name="FoodMart">
  <!-- Shared dimensions -->
  <Dimension name="Store">
    <Hierarchy hasAll="true" primaryKey="store_id">
      <Table name="store"/>
      <Level name="Store Country" column="store_country" uniqueMembers="true"/>
      <Level name="Store State" column="store_state" uniqueMembers="true"/>
      <Level name="Store City" column="store_city" uniqueMembers="false"/>
      <Level name="Store Name" column="store_name" uniqueMembers="true">
        <Property name="Store Type" column="store_type"/>
        <Property name="Store Manager" column="store_manager"/>
        <Property name="Store Sqft" column="store_sqft" type="Numeric"/>
        <Property name="Grocery Sqft" column="grocery_sqft" type="Numeric"/>
        <Property name="Frozen Sqft" column="frozen_sqft" type="Numeric"/>
        <Property name="Meat Sqft" column="meat_sqft" type="Numeric"/>
        <Property name="Has coffee bar" column="coffee_bar" type="Boolean"/>
        <Property name="Street address" column="store_street_address" type="String"/>
      </Level>
    </Hierarchy>
  </Dimension>
  <Dimension name="Store Size in SQFT">
    <Hierarchy hasAll="true" primaryKey="store_id">
      <Table name="store"/>
      <Level name="Store Sqft" column="store_sqft" type="Numeric" uniqueMembers="true"/>
    </Hierarchy>
  </Dimension>
  <Dimension name="Store Type">
    <Hierarchy hasAll="true" primaryKey="store_id">
      <Table name="store"/>
      <Level name="Store Type" column="store_type" uniqueMembers="true"/>
    </Hierarchy>
  </Dimension>
  <Dimension name="Time" type="Time">
    <Hierarchy hasAll="false" primaryKey="time_id">
      <Table name="time_by_day"/>
      <Level name="Year" column="the_year" type="Numeric" uniqueMembers="true" levelType="TimeYears"/>
      <Level name="Quarter" column="quarter" type="Numeric" uniqueMembers="false" levelType="TimeQuarters"/>
      <Level name="Month" column="month_of_year" type="Numeric" uniqueMembers="false" levelType="TimeMonths"/>
    </Hierarchy>
    <Hierarchy hasAll="true" name="Weekly" primaryKey="time_id">
      <Table name="time_by_day"/>
      <Level name="Year" column="the_year" type="Numeric" uniqueMembers="true" levelType="TimeYears"/>
      <Level name="Week" column="week_of_year" type="Numeric" uniqueMembers="false" levelType="TimeWeeks"/>
      <Level name="Day" column="day_of_month" type="Numeric" uniqueMembers="false" levelType="TimeDays"/>
    </Hierarchy>
    <Hierarchy hasAll="true" name="Datetime" primaryKey="time_id">
      <Table name="time_by_day"/>
      <Level name="Datetime" column="the_date" uniqueMembers="true" type="Datetime" levelType="TimeDays"/>
    </Hierarchy>
  </Dimension>
  <Dimension name="Time (exp)" type="Time">
    <Hierarchy hasAll="false" primaryKey="time_id">
      <Table name="time_by_day"/>
      <Level name="Year" uniqueMembers="true" type="Numeric" levelType="TimeYears">
        <KeyExpression>
          <SQL dialect="postgres">'Y' || CAST(EXTRACT(YEAR FROM time_by_day.the_date) AS INTEGER)</SQL>
          <SQL dialect="generic">the_year</SQL>
        </KeyExpression>
      </Level>
      <Level name="Quarter" uniqueMembers="false" type="Numeric" levelType="TimeQuarters">
        <KeyExpression>
          <SQL dialect="postgres">'Q' || CAST(EXTRACT(QUARTER FROM time_by_day.the_date) AS INTEGER)</SQL>
          <SQL dialect="generic">quarter</SQL>
        </KeyExpression>
      </Level>
      <Level name="Month" uniqueMembers="false" type="Numeric" levelType="TimeMonths">
        <KeyExpression>
          <SQL dialect="postgres">'M' || CAST(EXTRACT(MONTH FROM time_by_day.the_date) AS INTEGER)</SQL>
          <SQL dialect="generic">month_of_year</SQL>
        </KeyExpression>
      </Level>
    </Hierarchy>
    <Hierarchy hasAll="true" name="Weekly (exp)" primaryKey="time_id">
      <Table name="time_by_day"/>
      <Level name="Year" uniqueMembers="true" type="Numeric" levelType="TimeYears">
        <KeyExpression>
          <SQL dialect="postgres">'Y' || CAST(EXTRACT(YEAR FROM time_by_day.the_date) AS INTEGER)</SQL>
          <SQL dialect="generic">the_year</SQL>
        </KeyExpression>
      </Level>
      <Level name="Week" uniqueMembers="false" type="Numeric" levelType="TimeWeeks">
        <KeyExpression>
          <SQL dialect="postgres">'W' || CAST(EXTRACT(WEEK FROM time_by_day.the_date) AS INTEGER)</SQL>
          <SQL dialect="generic">week_of_year</SQL>
        </KeyExpression>
      </Level>
      <Level name="Day" uniqueMembers="false" type="Numeric" levelType="TimeDays">
        <KeyExpression>
          <SQL dialect="postgres">'D' || CAST(EXTRACT(DAY FROM time_by_day.the_date) AS INTEGER)</SQL>
          <SQL dialect="generic">day_of_month</SQL>
        </KeyExpression>
      </Level>
    </Hierarchy>
  </Dimension>
  <Dimension name="Product">
    <Hierarchy hasAll="true" primaryKey="product_id" primaryKeyTable="product">
      <Join leftKey="product_class_id" rightKey="product_class_id">
        <Table name="product"/>
        <Table name="product_class"/>
      </Join>
      <!--
        <Query>
        <SQL dialect="generic">
          SELECT *
          FROM "product", "product_class"
          WHERE "product"."product_class_id" = "product_class"."product_class_id"
        </SQL>
        </Query>
        <Level name="Product Family" column="product_family" uniqueMembers="true"/>
        <Level name="Product Department" column="product_department" uniqueMembers="false"/>
        <Level name="Product Category" column="product_category" uniqueMembers="false"/>
        <Level name="Product Subcategory" column="product_subcategory" uniqueMembers="false"/>
        <Level name="Brand Name" column="brand_name" uniqueMembers="false"/>
        <Level name="Product Name" column="product_name" uniqueMembers="true"/>
      -->
      <Level name="Product Family" table="product_class" column="product_family" uniqueMembers="true"/>
      <Level name="Product Department" table="product_class" column="product_department" uniqueMembers="false"/>
      <Level name="Product Category" table="product_class" column="product_category" uniqueMembers="false"/>
      <Level name="Product Subcategory" table="product_class" column="product_subcategory" uniqueMembers="false"/>
      <Level name="Brand Name" table="product" column="brand_name" uniqueMembers="false"/>
      <Level name="Product Name" table="product" column="product_name" uniqueMembers="true"/>
    </Hierarchy>
  </Dimension>
  <Dimension name="Warehouse">
    <Hierarchy hasAll="true" primaryKey="warehouse_id">
      <Table name="warehouse"/>
      <Level name="Country" column="warehouse_country" uniqueMembers="true"/>
      <Level name="State Province" column="warehouse_state_province" uniqueMembers="true"/>
      <Level name="City" column="warehouse_city" uniqueMembers="false"/>
      <Level name="Warehouse Name" column="warehouse_name" uniqueMembers="true"/>
    </Hierarchy>
  </Dimension>
  <!-- Sales -->
  <Cube name="Sales" defaultMeasure="Unit Sales">
    <Table name="sales_fact_1997">
      <!--
        <AggExclude name="agg_l_03_sales_fact_1997" />
        <AggExclude name="agg_ll_01_sales_fact_1997" />
        <AggExclude name="agg_pl_01_sales_fact_1997" />
        <AggExclude name="agg_l_05_sales_fact_1997" />
      -->
      <AggExclude name="agg_c_special_sales_fact_1997"/>
      <!--
        <AggExclude name="agg_c_14_sales_fact_1997" />
      -->
      <AggExclude name="agg_lc_100_sales_fact_1997"/>
      <AggExclude name="agg_lc_10_sales_fact_1997"/>
      <AggExclude name="agg_pc_10_sales_fact_1997"/>
      <AggName name="agg_c_special_sales_fact_1997">
        <AggFactCount column="FACT_COUNT"/>
        <AggIgnoreColumn column="foo"/>
        <AggIgnoreColumn column="bar"/>
        <AggForeignKey factColumn="product_id" aggColumn="PRODUCT_ID"/>
        <AggForeignKey factColumn="customer_id" aggColumn="CUSTOMER_ID"/>
        <AggForeignKey factColumn="promotion_id" aggColumn="PROMOTION_ID"/>
        <AggForeignKey factColumn="store_id" aggColumn="STORE_ID"/>
        <!--
            <AggMeasure name="[Measures].[Avg Unit Sales]" column="UNIT_SALES_AVG"/>
        -->
        <AggMeasure name="[Measures].[Unit Sales]" column="UNIT_SALES_SUM"/>
        <AggMeasure name="[Measures].[Store Cost]" column="STORE_COST_SUM"/>
        <AggMeasure name="[Measures].[Store Sales]" column="STORE_SALES_SUM"/>
        <AggLevel name="[Time].[Year]" column="TIME_YEAR"/>
        <AggLevel name="[Time].[Quarter]" column="TIME_QUARTER"/>
        <AggLevel name="[Time].[Month]" column="TIME_MONTH"/>
      </AggName>
    </Table>
    <!--
    <Dimension name="Bug">
      <Hierarchy hasAll="true">
        <Level name="Bug function" column="customer_id" uniqueMembers="true">
          <KeyExpression>
            <SQL dialect="generic">SUBSTR(customer_id, 1, 1)</SQL>
          </KeyExpression>
        </Level>
        <Level name="Bug function2" column="customer_id" uniqueMembers="true">
          <KeyExpression>
            <SQL dialect="generic">CASE WHEN LENGTH(customer_id || '') > 1 THEN SUBSTR(customer_id || '', 2, 1) ELSE SUBSTR(customer_id || '', 1, 1) END</SQL>
          </KeyExpression>
        </Level>
      </Hierarchy>
    </Dimension>
    -->
    <DimensionUsage name="Store" source="Store" foreignKey="store_id"/>
    <DimensionUsage name="Store Size in SQFT" source="Store Size in SQFT" foreignKey="store_id"/>
    <DimensionUsage name="Store Type" source="Store Type" foreignKey="store_id"/>
      <Dimension name="Normalized Store Location"  foreignKey="store_id">
        <Hierarchy hasAll="true" primaryKey="store_id" primaryKeyTable="store">
            <Join leftKey="region_id" rightKey="region_id">
                <Table name="store"/>
                <Join leftKey="sales_district_id" rightKey="district_id">
                  <Table name="region"/>
                  <Table name="district"/>
                </Join>
            </Join>
            <Level name="Country" table="district" column="country" uniqueMembers="true"/>
            <Level name="Province" table="district" column="state_province" uniqueMembers="true"/>
            <Level name="District" table="district" column="district" uniqueMembers="true"/>
        </Hierarchy>
      </Dimension>
    <DimensionUsage name="Time" source="Time" foreignKey="time_id"/>
    <DimensionUsage name="Time (exp)" source="Time (exp)" foreignKey="time_id"/>
    <DimensionUsage name="Product" source="Product" foreignKey="product_id"/>
    <Dimension name="Promotion Media" foreignKey="promotion_id">
      <Hierarchy hasAll="true" allMemberName="All Media" primaryKey="promotion_id" defaultMember="All Media">
        <Table name="promotion"/>
        <Level name="Media Type" column="media_type" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Promotions" foreignKey="promotion_id">
      <Hierarchy hasAll="true" allMemberName="All Promotions" primaryKey="promotion_id" defaultMember="[All Promotions]">
        <Table name="promotion"/>
        <Level name="Promotion Name" column="promotion_name" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Customers" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Customers" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Country" column="country" uniqueMembers="true"/>
        <Level name="State Province" column="state_province" uniqueMembers="true"/>
        <Level name="City" column="city" uniqueMembers="false"/>
        <Level name="Name" column="customer_id" type="Numeric" uniqueMembers="true">
          <NameExpression>
            <SQL dialect="oracle">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="access">fname + ' ' + lname</SQL>
            <SQL dialect="postgres">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="mysql">CONCAT(`customer`.`fname`, ' ', `customer`.`lname`)</SQL>
            <SQL dialect="mssql">fname + ' ' + lname</SQL>
            <SQL dialect="derby">"customer"."fullname"</SQL>
            <SQL dialect="db2">CONCAT(CONCAT("customer"."fname", ' '), "customer"."lname")</SQL>
            <SQL dialect="luciddb">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="teradata">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="generic">"fname"</SQL>
          </NameExpression>
          <OrdinalExpression>
            <SQL dialect="oracle">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="access">fname + ' ' + lname</SQL>
            <SQL dialect="postgres">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="mysql">CONCAT(`customer`.`fname`, ' ', `customer`.`lname`)</SQL>
            <SQL dialect="mssql">fname + ' ' + lname</SQL>
            <SQL dialect="derby">"customer"."fullname"</SQL>
            <SQL dialect="db2">CONCAT(CONCAT("customer"."fname", ' '), "customer"."lname")</SQL>
            <SQL dialect="luciddb">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="generic">"fname"</SQL>
          </OrdinalExpression>
          <Property name="Gender" column="gender"/>
          <Property name="Marital Status" column="marital_status"/>
          <Property name="Education" column="education"/>
          <Property name="Yearly Income" column="yearly_income"/>
        </Level>
      </Hierarchy>
    </Dimension>
    <Dimension name="Education Level" foreignKey="customer_id">
      <Hierarchy hasAll="true" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Education Level" column="education" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Gender" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Gender" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Gender" column="gender" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Marital Status" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Marital Status" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Marital Status" column="marital_status" uniqueMembers="true" approxRowCount="111"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Yearly Income" foreignKey="customer_id">
      <Hierarchy hasAll="true" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Yearly Income" column="yearly_income" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="Standard"/>
    <Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00"/>
    <Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.00"/>
    <Measure name="Sales Count" column="product_id" aggregator="count" formatString="#,###"/>
    <Measure name="Customer Count" column="customer_id" aggregator="distinct-count" formatString="#,###"/>
    <Measure name="Promotion Sales" aggregator="sum" formatString="#,###.00">
      <MeasureExpression>
        <SQL dialect="access">Iif("sales_fact_1997"."promotion_id" = 0, 0, "sales_fact_1997"."store_sales")</SQL>
        <SQL dialect="oracle">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="postgres">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="mysql">(case when `sales_fact_1997`.`promotion_id` = 0 then 0 else `sales_fact_1997`.`store_sales` end)</SQL>
        <!-- Workaround the fact that Infobright does not have a CASE operator. The simpler expression gives wrong results, so some tests are disabled. -->
        <SQL dialect="infobright">`sales_fact_1997`.`store_sales`</SQL>
        <SQL dialect="derby">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="luciddb">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="db2">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="generic">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
      </MeasureExpression>
    </Measure>
    <CalculatedMember name="Profit" dimension="Measures">
      <Formula>[Measures].[Store Sales] - [Measures].[Store Cost]</Formula>
      <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
    </CalculatedMember>
    <CalculatedMember name="Profit last Period" dimension="Measures" formula="COALESCEEMPTY(SEARCH([Measures].[Profit], Time.PREVMEMBER), [Measures].[Profit])" visible="true">
      <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="18"/>
    </CalculatedMember>
    <CalculatedMember name="Profit Growth" dimension="Measures" formula="([Measures].[Profit] - [Measures].[Profit last Period]) / [Measures].[Profit last Period]" visible="true" caption="Gewinn-Wachstum">
      <CalculatedMemberProperty name="FORMAT_STRING" value="0.0%"/>
    </CalculatedMember>
  </Cube>
  <!-- Sales (no-agg) (Same as Sales w/o aggregation) -->
  <Cube name="Sales (no-agg)" defaultMeasure="Unit Sales">
    <Table name="sales_fact_1997" />
    <DimensionUsage name="Store" source="Store" foreignKey="store_id"/>
    <DimensionUsage name="Store Size in SQFT" source="Store Size in SQFT" foreignKey="store_id"/>
    <DimensionUsage name="Store Type" source="Store Type" foreignKey="store_id"/>
      <Dimension name="Normalized Store Location"  foreignKey="store_id">
        <Hierarchy hasAll="true" primaryKey="store_id" primaryKeyTable="store">
            <Join leftKey="region_id" rightKey="region_id">
                <Table name="store"/>
                <Join leftKey="sales_district_id" rightKey="district_id">
                  <Table name="region"/>
                  <Table name="district"/>
                </Join>
            </Join>
            <Level name="Country" table="district" column="country" uniqueMembers="true"/>
            <Level name="Province" table="district" column="state_province" uniqueMembers="true"/>
            <Level name="District" table="district" column="district" uniqueMembers="true"/>
        </Hierarchy>
      </Dimension>
    <DimensionUsage name="Time" source="Time" foreignKey="time_id"/>
    <DimensionUsage name="Time (exp)" source="Time (exp)" foreignKey="time_id"/>
    <DimensionUsage name="Product" source="Product" foreignKey="product_id"/>
    <Dimension name="Promotion Media" foreignKey="promotion_id">
      <Hierarchy hasAll="true" allMemberName="All Media" primaryKey="promotion_id" defaultMember="All Media">
        <Table name="promotion"/>
        <Level name="Media Type" column="media_type" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Promotions" foreignKey="promotion_id">
      <Hierarchy hasAll="true" allMemberName="All Promotions" primaryKey="promotion_id" defaultMember="[All Promotions]">
        <Table name="promotion"/>
        <Level name="Promotion Name" column="promotion_name" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Customers" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Customers" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Country" column="country" uniqueMembers="true"/>
        <Level name="State Province" column="state_province" uniqueMembers="true"/>
        <Level name="City" column="city" uniqueMembers="false"/>
        <Level name="Name" column="customer_id" type="Numeric" uniqueMembers="true">
          <NameExpression>
            <SQL dialect="oracle">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="access">fname + ' ' + lname</SQL>
            <SQL dialect="postgres">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="mysql">CONCAT(`customer`.`fname`, ' ', `customer`.`lname`)</SQL>
            <SQL dialect="mssql">fname + ' ' + lname</SQL>
            <SQL dialect="derby">"customer"."fullname"</SQL>
            <SQL dialect="db2">CONCAT(CONCAT("customer"."fname", ' '), "customer"."lname")</SQL>
            <SQL dialect="luciddb">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="teradata">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="generic">"fname"</SQL>
          </NameExpression>
          <OrdinalExpression>
            <SQL dialect="oracle">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="access">fname + ' ' + lname</SQL>
            <SQL dialect="postgres">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="mysql">CONCAT(`customer`.`fname`, ' ', `customer`.`lname`)</SQL>
            <SQL dialect="mssql">fname + ' ' + lname</SQL>
            <SQL dialect="derby">"customer"."fullname"</SQL>
            <SQL dialect="db2">CONCAT(CONCAT("customer"."fname", ' '), "customer"."lname")</SQL>
            <SQL dialect="luciddb">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="generic">"fname"</SQL>
          </OrdinalExpression>
          <Property name="Gender" column="gender"/>
          <Property name="Marital Status" column="marital_status"/>
          <Property name="Education" column="education"/>
          <Property name="Yearly Income" column="yearly_income"/>
        </Level>
      </Hierarchy>
    </Dimension>
    <Dimension name="Education Level" foreignKey="customer_id">
      <Hierarchy hasAll="true" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Education Level" column="education" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Gender" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Gender" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Gender" column="gender" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Marital Status" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Marital Status" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Marital Status" column="marital_status" uniqueMembers="true" approxRowCount="111"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Yearly Income" foreignKey="customer_id">
      <Hierarchy hasAll="true" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Yearly Income" column="yearly_income" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="Standard"/>
    <Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00"/>
    <Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.00"/>
    <Measure name="Sales Count" column="product_id" aggregator="count" formatString="#,###"/>
    <Measure name="Customer Count" column="customer_id" aggregator="distinct-count" formatString="#,###"/>
    <Measure name="Promotion Sales" aggregator="sum" formatString="#,###.00">
      <MeasureExpression>
        <SQL dialect="access">Iif("sales_fact_1997"."promotion_id" = 0, 0, "sales_fact_1997"."store_sales")</SQL>
        <SQL dialect="oracle">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="postgres">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="mysql">(case when `sales_fact_1997`.`promotion_id` = 0 then 0 else `sales_fact_1997`.`store_sales` end)</SQL>
        <!-- Workaround the fact that Infobright does not have a CASE operator. The simpler expression gives wrong results, so some tests are disabled. -->
        <SQL dialect="infobright">`sales_fact_1997`.`store_sales`</SQL>
        <SQL dialect="derby">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="luciddb">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="db2">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="generic">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
      </MeasureExpression>
    </Measure>
    <CalculatedMember name="Profit" dimension="Measures">
      <Formula>[Measures].[Store Sales] - [Measures].[Store Cost]</Formula>
      <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
    </CalculatedMember>
    <CalculatedMember name="Profit last Period" dimension="Measures" formula="COALESCEEMPTY(SEARCH([Measures].[Profit], Time.PREVMEMBER), [Measures].[Profit])" visible="true">
      <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="18"/>
    </CalculatedMember>
    <CalculatedMember name="Profit Growth" dimension="Measures" formula="([Measures].[Profit] - [Measures].[Profit last Period]) / [Measures].[Profit last Period]" visible="true" caption="Gewinn-Wachstum">
      <CalculatedMemberProperty name="FORMAT_STRING" value="0.0%"/>
    </CalculatedMember>
  </Cube>
  <Cube name="Sales Scenario" defaultMeasure="Unit Sales">
    <Table name="sales_fact_1997">
      <!--
        <AggExclude name="agg_l_03_sales_fact_1997" />
        <AggExclude name="agg_ll_01_sales_fact_1997" />
        <AggExclude name="agg_pl_01_sales_fact_1997" />
        <AggExclude name="agg_l_05_sales_fact_1997" />
      -->
      <AggExclude name="agg_c_special_sales_fact_1997"/>
      <!--
        <AggExclude name="agg_c_14_sales_fact_1997" />
      -->
      <AggExclude name="agg_lc_100_sales_fact_1997"/>
      <AggExclude name="agg_lc_10_sales_fact_1997"/>
      <AggExclude name="agg_pc_10_sales_fact_1997"/>
      <AggName name="agg_c_special_sales_fact_1997">
        <AggFactCount column="FACT_COUNT"/>
        <AggIgnoreColumn column="foo"/>
        <AggIgnoreColumn column="bar"/>
        <AggForeignKey factColumn="product_id" aggColumn="PRODUCT_ID"/>
        <AggForeignKey factColumn="customer_id" aggColumn="CUSTOMER_ID"/>
        <AggForeignKey factColumn="promotion_id" aggColumn="PROMOTION_ID"/>
        <AggForeignKey factColumn="store_id" aggColumn="STORE_ID"/>
        <!--
          <AggMeasure name="[Measures].[Avg Unit Sales]" column="UNIT_SALES_AVG"/>
        -->
        <AggMeasure name="[Measures].[Unit Sales]" column="UNIT_SALES_SUM"/>
        <AggMeasure name="[Measures].[Store Cost]" column="STORE_COST_SUM"/>
        <AggMeasure name="[Measures].[Store Sales]" column="STORE_SALES_SUM"/>
        <AggLevel name="[Time].[Year]" column="TIME_YEAR"/>
        <AggLevel name="[Time].[Quarter]" column="TIME_QUARTER"/>
        <AggLevel name="[Time].[Month]" column="TIME_MONTH"/>
      </AggName>
    </Table>
    <DimensionUsage name="Store" source="Store" foreignKey="store_id"/>
    <DimensionUsage name="Store Size in SQFT" source="Store Size in SQFT" foreignKey="store_id"/>
    <DimensionUsage name="Store Type" source="Store Type" foreignKey="store_id"/>
    <DimensionUsage name="Time" source="Time" foreignKey="time_id"/>
    <DimensionUsage name="Product" source="Product" foreignKey="product_id"/>
    <Dimension name="Promotion Media" foreignKey="promotion_id">
      <Hierarchy hasAll="true" allMemberName="All Media" primaryKey="promotion_id" defaultMember="All Media">
        <Table name="promotion"/>
        <Level name="Media Type" column="media_type" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Promotions" foreignKey="promotion_id">
      <Hierarchy hasAll="true" allMemberName="All Promotions" primaryKey="promotion_id" defaultMember="[All Promotions]">
        <Table name="promotion"/>
        <Level name="Promotion Name" column="promotion_name" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Customers" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Customers" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Country" column="country" uniqueMembers="true"/>
        <Level name="State Province" column="state_province" uniqueMembers="true"/>
        <Level name="City" column="city" uniqueMembers="false"/>
        <Level name="Name" column="customer_id" type="Numeric" uniqueMembers="true">
          <NameExpression>
            <SQL dialect="oracle">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="access">fname + ' ' + lname</SQL>
            <SQL dialect="postgres">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="mysql">CONCAT(`customer`.`fname`, ' ', `customer`.`lname`)</SQL>
            <SQL dialect="mssql">fname + ' ' + lname</SQL>
            <SQL dialect="derby">"customer"."fullname"</SQL>
            <SQL dialect="db2">CONCAT(CONCAT("customer"."fname", ' '), "customer"."lname")</SQL>
            <SQL dialect="luciddb">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="teradata">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="generic">"fname"</SQL>
          </NameExpression>
          <OrdinalExpression>
            <SQL dialect="oracle">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="access">fname + ' ' + lname</SQL>
            <SQL dialect="postgres">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="mysql">CONCAT(`customer`.`fname`, ' ', `customer`.`lname`)</SQL>
            <SQL dialect="mssql">fname + ' ' + lname</SQL>
            <SQL dialect="derby">"customer"."fullname"</SQL>
            <SQL dialect="db2">CONCAT(CONCAT("customer"."fname", ' '), "customer"."lname")</SQL>
            <SQL dialect="luciddb">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="generic">"fname"</SQL>
          </OrdinalExpression>
          <Property name="Gender" column="gender"/>
          <Property name="Marital Status" column="marital_status"/>
          <Property name="Education" column="education"/>
          <Property name="Yearly Income" column="yearly_income"/>
        </Level>
      </Hierarchy>
    </Dimension>
    <Dimension name="Education Level" foreignKey="customer_id">
      <Hierarchy hasAll="true" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Education Level" column="education" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Gender" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Gender" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Gender" column="gender" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Marital Status" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Marital Status" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Marital Status" column="marital_status" uniqueMembers="true" approxRowCount="111"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Yearly Income" foreignKey="customer_id">
      <Hierarchy hasAll="true" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Yearly Income" column="yearly_income" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="Standard"/>
    <Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00"/>
    <Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.00"/>
    <Measure name="Sales Count" column="product_id" aggregator="count" formatString="#,###"/>
    <Measure name="Customer Count" column="customer_id" aggregator="distinct-count" formatString="#,###"/>
    <Measure name="Promotion Sales" aggregator="sum" formatString="#,###.00">
      <MeasureExpression>
        <SQL dialect="access">Iif("sales_fact_1997"."promotion_id" = 0, 0, "sales_fact_1997"."store_sales")</SQL>
        <SQL dialect="oracle">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="postgres">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="mysql">(case when `sales_fact_1997`.`promotion_id` = 0 then 0 else `sales_fact_1997`.`store_sales` end)</SQL>
        <!-- Workaround the fact that Infobright does not have a CASE operator. The simpler expression gives wrong results, so some tests are disabled. -->
        <SQL dialect="infobright">`sales_fact_1997`.`store_sales`</SQL>
        <SQL dialect="derby">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="luciddb">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="db2">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
        <SQL dialect="generic">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
      </MeasureExpression>
    </Measure>
    <CalculatedMember name="Profit" dimension="Measures">
      <Formula>[Measures].[Store Sales] - [Measures].[Store Cost]</Formula>
      <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
    </CalculatedMember>
    <CalculatedMember name="Profit last Period" dimension="Measures" formula="COALESCEEMPTY(SEARCH([Measures].[Profit], Time.PREVMEMBER), [Measures].[Profit])" visible="false">
      <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="18"/>
    </CalculatedMember>
    <CalculatedMember name="Profit Growth" dimension="Measures" formula="([Measures].[Profit] - [Measures].[Profit last Period]) / [Measures].[Profit last Period]" visible="true" caption="Gewinn-Wachstum">
      <CalculatedMemberProperty name="FORMAT_STRING" value="0.0%"/>
    </CalculatedMember>
  </Cube>
  <Cube name="Warehouse">
    <Table name="inventory_fact_1997"/>
    <DimensionUsage name="Store" source="Store" foreignKey="store_id"/>
    <DimensionUsage name="Store Size in SQFT" source="Store Size in SQFT" foreignKey="store_id"/>
    <DimensionUsage name="Store Type" source="Store Type" foreignKey="store_id"/>
    <DimensionUsage name="Time" source="Time" foreignKey="time_id"/>
    <DimensionUsage name="Product" source="Product" foreignKey="product_id"/>
    <DimensionUsage name="Warehouse" source="Warehouse" foreignKey="warehouse_id"/>
    <Measure name="Store Invoice" column="store_invoice" aggregator="sum"/>
    <Measure name="Supply Time" column="supply_time" aggregator="sum"/>
    <Measure name="Warehouse Cost" column="warehouse_cost" aggregator="sum"/>
    <Measure name="Warehouse Sales" column="warehouse_sales" aggregator="sum"/>
    <Measure name="Units Shipped" column="units_shipped" aggregator="sum" formatString="#.0"/>
    <Measure name="Units Ordered" column="units_ordered" aggregator="sum" formatString="#.0"/>
    <Measure name="Warehouse Profit" aggregator="sum">
      <MeasureExpression>
        <SQL dialect="mysql">`warehouse_sales` - `inventory_fact_1997`.`warehouse_cost`</SQL>
        <SQL dialect="infobright">`warehouse_sales` - `inventory_fact_1997`.`warehouse_cost`</SQL>
        <SQL dialect="generic">&quot;warehouse_sales&quot; - &quot;inventory_fact_1997&quot;.&quot;warehouse_cost&quot;</SQL>
      </MeasureExpression>
    </Measure>
    <CalculatedMember name="Average Warehouse Sale" dimension="Measures">
      <Formula>[Measures].[Warehouse Sales] / [Measures].[Warehouse Cost]</Formula>
      <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
    </CalculatedMember>
    <NamedSet name="Top Sellers">
      <Formula>TopCount([Warehouse].[Warehouse Name].MEMBERS, 5, [Measures].[Warehouse Sales])</Formula>
    </NamedSet>
  </Cube>
  <!-- Test a cube based on a single table. -->
  <Cube name="Store">
    <Table name="store"/>
    <!-- We could have used the shared dimension "Store Type", but we want to test private dimensions without primary key. -->
    <Dimension name="Store Type">
      <Hierarchy hasAll="true">
        <Level name="Store Type" column="store_type" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <!-- There is no need to specify primary key or foreign key, since the shared dimension "Store" has the same underlying table as the cube. -->
    <DimensionUsage name="Store" source="Store"/>
    <Dimension name="Has coffee bar">
      <Hierarchy hasAll="true">
        <Level name="Has coffee bar" column="coffee_bar" uniqueMembers="true" type="Boolean"/>
      </Hierarchy>
    </Dimension>
    <Measure name="Store Sqft" column="store_sqft" aggregator="sum" formatString="#,###"/>
    <Measure name="Grocery Sqft" column="grocery_sqft" aggregator="sum" formatString="#,###"/>
  </Cube>
  <Cube name="HR">
    <Table name="salary"/>
    <!-- Use private "Time" dimension because key is different than public "Time" dimension. -->
    <Dimension name="Time" type="Time" foreignKey="pay_date">
      <Hierarchy hasAll="false" primaryKey="the_date">
        <Table name="time_by_day"/>
        <Level name="Year" column="the_year" type="Numeric" uniqueMembers="true" levelType="TimeYears"/>
        <Level name="Quarter" column="quarter" uniqueMembers="false" levelType="TimeQuarters"/>
        <!-- Use the_month as source for the name, so members look like
       [Time].[1997].[Q1].[Jan] rather than [Time].[1997].[Q1].[1]. -->
        <Level name="Month" column="month_of_year" nameColumn="the_month" uniqueMembers="false" type="Numeric" levelType="TimeMonths"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Store" foreignKey="employee_id">
      <Hierarchy hasAll="true" primaryKey="employee_id" primaryKeyTable="employee">
        <Join leftKey="store_id" rightKey="store_id">
          <Table name="employee"/>
          <Table name="store"/>
        </Join>
        <Level name="Store Country" table="store" column="store_country" uniqueMembers="true"/>
        <Level name="Store State" table="store" column="store_state" uniqueMembers="true"/>
        <Level name="Store City" table="store" column="store_city" uniqueMembers="false"/>
        <Level name="Store Name" table="store" column="store_name" uniqueMembers="true">
          <Property name="Store Type" column="store_type"/>
          <Property name="Store Manager" column="store_manager"/>
          <Property name="Store Sqft" column="store_sqft" type="Numeric"/>
          <Property name="Grocery Sqft" column="grocery_sqft" type="Numeric"/>
          <Property name="Frozen Sqft" column="frozen_sqft" type="Numeric"/>
          <Property name="Meat Sqft" column="meat_sqft" type="Numeric"/>
          <Property name="Has coffee bar" column="coffee_bar" type="Boolean"/>
          <Property name="Street address" column="store_street_address" type="String"/>
        </Level>
      </Hierarchy>
    </Dimension>
    <Dimension name="Pay Type" foreignKey="employee_id">
      <Hierarchy hasAll="true" primaryKey="employee_id" primaryKeyTable="employee">
        <Join leftKey="position_id" rightKey="position_id">
          <Table name="employee"/>
          <Table name="position"/>
        </Join>
        <Level name="Pay Type" table="position" column="pay_type" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Store Type" foreignKey="employee_id">
      <Hierarchy hasAll="true" primaryKeyTable="employee" primaryKey="employee_id">
        <Join leftKey="store_id" rightKey="store_id">
          <Table name="employee"/>
          <Table name="store"/>
        </Join>
        <Level name="Store Type" table="store" column="store_type" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Position" foreignKey="employee_id">
      <Hierarchy hasAll="true" allMemberName="All Position" primaryKey="employee_id">
        <Table name="employee"/>
        <Level name="Management Role" uniqueMembers="true" column="management_role"/>
        <Level name="Position Title" uniqueMembers="false" column="position_title" ordinalColumn="position_id"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Department" foreignKey="department_id">
      <Hierarchy hasAll="true" primaryKey="department_id">
        <Table name="department"/>
        <Level name="Department Description" uniqueMembers="true" column="department_id"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Employees" foreignKey="employee_id">
      <Hierarchy hasAll="true" allMemberName="All Employees" primaryKey="employee_id">
        <Table name="employee"/>
        <Level name="Employee Id" type="Numeric" uniqueMembers="true" column="employee_id" parentColumn="supervisor_id" nameColumn="full_name" nullParentValue="0">
          <Closure parentColumn="supervisor_id" childColumn="employee_id">
            <Table name="employee_closure"/>
          </Closure>
          <Property name="Marital Status" column="marital_status"/>
          <Property name="Position Title" column="position_title"/>
          <Property name="Gender" column="gender"/>
          <Property name="Salary" column="salary"/>
          <Property name="Education Level" column="education_level"/>
          <Property name="Management Role" column="management_role"/>
        </Level>
      </Hierarchy>
    </Dimension>
    <Measure name="Org Salary" column="salary_paid" aggregator="sum" formatString="Currency"/>
    <Measure name="Count" column="employee_id" aggregator="count" formatString="#,#"/>
    <Measure name="Number of Employees" column="employee_id" aggregator="distinct-count" formatString="#,#"/>
    <CalculatedMember name="Avg Salary" dimension="Measures" formatString="Currency" formula="[Measures].[Org Salary]/[Measures].[Number of Employees]"/>
  </Cube>
  <!-- Cube with one ragged hierarchy (otherwise the same as the "Sales" cube). -->
  <Cube name="Sales Ragged">
    <Table name="sales_fact_1997">
      <AggExclude name="agg_pc_10_sales_fact_1997"/>
      <AggExclude name="agg_lc_10_sales_fact_1997"/>
    </Table>
    <Dimension name="Store" foreignKey="store_id">
      <Hierarchy hasAll="true" primaryKey="store_id">
        <Table name="store_ragged"/>
        <Level name="Store Country" column="store_country" uniqueMembers="true" hideMemberIf="Never"/>
        <Level name="Store State" column="store_state" uniqueMembers="true" hideMemberIf="IfParentsName"/>
        <Level name="Store City" column="store_city" uniqueMembers="false" hideMemberIf="IfBlankName"/>
        <Level name="Store Name" column="store_name" uniqueMembers="true" hideMemberIf="Never">
          <Property name="Store Type" column="store_type"/>
          <Property name="Store Manager" column="store_manager"/>
          <Property name="Store Sqft" column="store_sqft" type="Numeric"/>
          <Property name="Grocery Sqft" column="grocery_sqft" type="Numeric"/>
          <Property name="Frozen Sqft" column="frozen_sqft" type="Numeric"/>
          <Property name="Meat Sqft" column="meat_sqft" type="Numeric"/>
          <Property name="Has coffee bar" column="coffee_bar" type="Boolean"/>
          <Property name="Street address" column="store_street_address" type="String"/>
        </Level>
      </Hierarchy>
    </Dimension>
    <Dimension name="Geography" foreignKey="store_id">
      <Hierarchy hasAll="true" primaryKey="store_id">
        <Table name="store_ragged"/>
        <Level name="Country" column="store_country" uniqueMembers="true" hideMemberIf="Never"/>
        <Level name="State" column="store_state" uniqueMembers="true" hideMemberIf="IfParentsName"/>
        <Level name="City" column="store_city" uniqueMembers="false" hideMemberIf="IfBlankName"/>
      </Hierarchy>
    </Dimension>
    <DimensionUsage name="Store Size in SQFT" source="Store Size in SQFT" foreignKey="store_id"/>
    <DimensionUsage name="Store Type" source="Store Type" foreignKey="store_id"/>
    <DimensionUsage name="Time" source="Time" foreignKey="time_id"/>
    <DimensionUsage name="Product" source="Product" foreignKey="product_id"/>
    <Dimension name="Promotion Media" foreignKey="promotion_id">
      <Hierarchy hasAll="true" allMemberName="All Media" primaryKey="promotion_id">
        <Table name="promotion"/>
        <Level name="Media Type" column="media_type" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Promotions" foreignKey="promotion_id">
      <Hierarchy hasAll="true" allMemberName="All Promotions" primaryKey="promotion_id">
        <Table name="promotion"/>
        <Level name="Promotion Name" column="promotion_name" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Customers" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Customers" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Country" column="country" uniqueMembers="true"/>
        <Level name="State Province" column="state_province" uniqueMembers="true"/>
        <Level name="City" column="city" uniqueMembers="false"/>
        <Level name="Name" uniqueMembers="true">
          <KeyExpression>
            <SQL dialect="oracle">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="access">fname + ' ' + lname</SQL>
            <SQL dialect="postgres">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="mysql">CONCAT(`customer`.`fname`, ' ', `customer`.`lname`)</SQL>
            <SQL dialect="mssql">fname + ' ' + lname</SQL>
            <SQL dialect="derby">"customer"."fullname"</SQL>
            <SQL dialect="db2">CONCAT(CONCAT("customer"."fname", ' '), "customer"."lname")</SQL>
            <SQL dialect="luciddb">"fname" || ' ' || "lname"</SQL>
            <SQL dialect="generic">"fname"</SQL>
          </KeyExpression>
          <Property name="Gender" column="gender"/>
          <Property name="Marital Status" column="marital_status"/>
          <Property name="Education" column="education"/>
          <Property name="Yearly Income" column="yearly_income"/>
        </Level>
      </Hierarchy>
    </Dimension>
    <Dimension name="Education Level" foreignKey="customer_id">
      <Hierarchy hasAll="true" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Education Level" column="education" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Gender" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Gender" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Gender" column="gender" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Marital Status" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Marital Status" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Marital Status" column="marital_status" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Dimension name="Yearly Income" foreignKey="customer_id">
      <Hierarchy hasAll="true" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Yearly Income" column="yearly_income" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="Standard"/>
    <Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00"/>
    <Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.00"/>
    <Measure name="Sales Count" column="product_id" aggregator="count" formatString="#,###"/>
    <Measure name="Customer Count" column="customer_id" aggregator="distinct-count" formatString="#,###"/>
  </Cube>
  <!-- a simpler version of "Sales" (with MEMBER_ORDINAL-properties) -->
  <Cube name="Sales 2">
    <Table name="sales_fact_1997"/>
    <DimensionUsage name="Time" source="Time" foreignKey="time_id"/>
    <DimensionUsage name="Product" source="Product" foreignKey="product_id"/>
    <Dimension name="Gender" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Gender" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Gender" column="gender" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Measure name="Sales Count" column="product_id" aggregator="count" formatString="#,###">
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="1"/>
    </Measure>
    <Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="Standard">
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="2"/>
    </Measure>
    <Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.00">
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="3"/>
    </Measure>
    <Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00">
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="6"/>
    </Measure>
    <Measure name="Customer Count" column="customer_id" aggregator="distinct-count" formatString="#,###">
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="7"/>
    </Measure>
    <CalculatedMember name="Profit" dimension="Measures">
      <Formula>[Measures].[Store Sales] - [Measures].[Store Cost]</Formula>
      <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="4"/>
    </CalculatedMember>
    <CalculatedMember name="Profit last Period" dimension="Measures" formula="COALESCEEMPTY(SEARCH([Measures].[Profit], Time.PREVMEMBER), [Measures].[Profit])" visible="false">
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="5"/>
    </CalculatedMember>
  </Cube>
  <!-- Cube with one ragged hierarchy (otherwise the same as the "Sales" cube). -->
  <Cube name="Test_Join" useLeftJoins="true">
    <Join leftKey="product_id,product_id" rightKey="product_id,product_id">
      <Table name="sales_fact_1997" />
      <Table name="product" />
    </Join>
    <Dimension name="Gender" foreignKey="customer_id">
      <Hierarchy hasAll="true" allMemberName="All Gender" primaryKey="customer_id">
        <Table name="customer"/>
        <Level name="Gender" column="gender" uniqueMembers="true"/>
      </Hierarchy>
    </Dimension>
    <Measure name="Sales Count" column="product_id" aggregator="count" formatString="#,###">
      <CalculatedMemberProperty name="MEMBER_ORDINAL" value="1"/>
    </Measure>
  </Cube>
  <VirtualCube name="Warehouse and Sales" defaultMeasure="Store Sales">
    <VirtualCubeDimension cubeName="Sales" name="Customers"/>
    <VirtualCubeDimension cubeName="Sales" name="Education Level"/>
    <VirtualCubeDimension cubeName="Sales" name="Gender"/>
    <VirtualCubeDimension cubeName="Sales" name="Marital Status"/>
    <VirtualCubeDimension name="Product"/>
    <VirtualCubeDimension cubeName="Sales" name="Promotion Media"/>
    <VirtualCubeDimension cubeName="Sales" name="Promotions"/>
    <VirtualCubeDimension name="Store"/>
    <VirtualCubeDimension name="Time"/>
    <VirtualCubeDimension cubeName="Sales" name="Yearly Income"/>
    <VirtualCubeDimension cubeName="Warehouse" name="Warehouse"/>
    <VirtualCubeMeasure cubeName="Sales" name="[Measures].[Sales Count]"/>
    <VirtualCubeMeasure cubeName="Sales" name="[Measures].[Store Cost]"/>
    <VirtualCubeMeasure cubeName="Sales" name="[Measures].[Store Sales]"/>
    <VirtualCubeMeasure cubeName="Sales" name="[Measures].[Unit Sales]"/>
    <VirtualCubeMeasure cubeName="Sales" name="[Measures].[Profit]"/>
    <VirtualCubeMeasure cubeName="Sales" name="[Measures].[Profit Growth]"/>
    <VirtualCubeMeasure cubeName="Warehouse" name="[Measures].[Store Invoice]"/>
    <VirtualCubeMeasure cubeName="Warehouse" name="[Measures].[Supply Time]"/>
    <VirtualCubeMeasure cubeName="Warehouse" name="[Measures].[Units Ordered]"/>
    <VirtualCubeMeasure cubeName="Warehouse" name="[Measures].[Units Shipped]"/>
    <VirtualCubeMeasure cubeName="Warehouse" name="[Measures].[Warehouse Cost]"/>
    <VirtualCubeMeasure cubeName="Warehouse" name="[Measures].[Warehouse Profit]"/>
    <VirtualCubeMeasure cubeName="Warehouse" name="[Measures].[Warehouse Sales]"/>
    <VirtualCubeMeasure cubeName="Warehouse" name="[Measures].[Average Warehouse Sale]"/>
    <!--
      <VirtualCubeMeasure cubeName="Sales" name="[Measures].[Store Sales Net]"/>
    -->
    <CalculatedMember name="Profit Per Unit Shipped" dimension="Measures">
      <Formula>[Measures].[Profit] / [Measures].[Units Shipped]</Formula>
    </CalculatedMember>
  </VirtualCube>
  <!-- A California manager can only see customers and stores in California. They cannot drill down on Gender. -->
  <Role name="California manager">
    <SchemaGrant access="none">
      <CubeGrant cube="Sales" access="all">
        <HierarchyGrant hierarchy="[Store]" access="custom" topLevel="[Store].[Store Country]">
          <MemberGrant member="[Store].[USA].[CA]" access="all"/>
          <MemberGrant member="[Store].[USA].[CA].[Los Angeles]" access="none"/>
        </HierarchyGrant>
        <HierarchyGrant hierarchy="[Customers]" access="custom" topLevel="[Customers].[State Province]" bottomLevel="[Customers].[City]">
          <MemberGrant member="[Customers].[USA].[CA]" access="all"/>
          <MemberGrant member="[Customers].[USA].[CA].[Los Angeles]" access="none"/>
        </HierarchyGrant>
        <HierarchyGrant hierarchy="[Gender]" access="none"/>
      </CubeGrant>
    </SchemaGrant>
  </Role>
  <Role name="No HR Cube">
    <SchemaGrant access="all">
      <CubeGrant cube="HR" access="none"/>
    </SchemaGrant>
  </Role>
  <!-- DEISTER CUSTOM -->
  <Geometries>
    <Geometry name="Store country (geom)" table="geo_countries" primaryKey="id_country">
      <Table name="store" columns="store_country" />
    </Geometry>
    <Geometry name="Store state (geom)" table="geo_states" primaryKey="id_country, id_state">
      <Table name="store" columns="store_country, store_state" />
    </Geometry>
    <Geometry name="Store city (geom)" table="geo_cities" primaryKey="id_country, id_state, id_city">
      <Table name="store" columns="store_country, store_state, store_city" />
    </Geometry>
  </Geometries>
  <MeasureRanges>
    <MeasureRange name="[Measures].[Unit Sales]">
      <Range min="0"      max="50000"     fg-color="#fff7ec" />
      <Range min="50000"    max="100000"    fg-color="#fee8c8" />
      <Range min="100000"   max="150000"    fg-color="#fdd49e" />
      <Range min="150000"   max="200000"    fg-color="#fdbb84" />
      <Range min="200000"   max="250000"    fg-color="#fc8d59" />
      <Range min="250000"   max="300000"    fg-color="#ef6548" />
      <Range min="300000"   max="350000"    fg-color="#d7301f" />
      <Range min="350000"   max="400000"    fg-color="#b30000" />
      <Range min="400000"   max="450000"    fg-color="#7f0000" />
      <Range min="500000"   max="550000"    fg-color="#640000" />
      <Range min="550000"   max="600000"    fg-color="#4A0000" />
    </MeasureRange>
    <MeasureRange name="[Measures].[Store Cost]">
      <Range min="0"      max="50000"     fg-color="#fff7fb" />
      <Range min="50000"    max="100000"    fg-color="#ece7f2" />
      <Range min="100000"   max="150000"    fg-color="#d0d1e6" />
      <Range min="150000"   max="200000"    fg-color="#a6bddb" />
      <Range min="200000"   max="250000"    fg-color="#74a9cf" />
      <Range min="250000"   max="300000"    fg-color="#3690c0" />
      <Range min="300000"   max="350000"    fg-color="#0570b0" />
      <Range min="350000"   max="400000"    fg-color="#045a8d" />
      <Range min="400000"   max="450000"    fg-color="#023858" />
      <Range min="500000"   max="550000"    fg-color="#012941" />
      <Range min="550000"   max="600000"    fg-color="#001522" />
    </MeasureRange>
    <MeasureRange name="[Measures].[Store Count]">
      <Range min="0"      max="50000"     fg-color="#f7fcfd" />
      <Range min="50000"    max="100000"    fg-color="#e0ecf4" />
      <Range min="100000"   max="150000"    fg-color="#bfd3e6" />
      <Range min="150000"   max="200000"    fg-color="#9ebcda" />
      <Range min="200000"   max="250000"    fg-color="#8c96c6" />
      <Range min="250000"   max="300000"    fg-color="#8c6bb1" />
      <Range min="300000"   max="350000"    fg-color="#88419d" />
      <Range min="350000"   max="400000"    fg-color="#810f7c" />
      <Range min="400000"   max="450000"    fg-color="#4d004b" />
      <Range min="500000"   max="550000"    fg-color="#40003F" />
      <Range min="550000"   max="600000"    fg-color="#350034" />
    </MeasureRange>
    <MeasureRange name="[Measures].[Sales Count]">
      <Range min="0"      max="5000"      fg-color="#ffffef" />
      <Range min="5000"     max="10000"     fg-color="#ffffe5" />
      <Range min="10000"    max="15000"     fg-color="#f7fcb9" />
      <Range min="15000"    max="20000"     fg-color="#d9f0a3" />
      <Range min="20000"    max="25000"     fg-color="#addd8e" />
      <Range min="25000"    max="30000"     fg-color="#78c679" />
      <Range min="30000"    max="35000"     fg-color="#41ab5d" />
      <Range min="35000"    max="40000"     fg-color="#238443" />
      <Range min="40000"    max="45000"     fg-color="#006837" />
      <Range min="50000"    max="55000"     fg-color="#004529" />
      <Range min="55000"    max="60000"     fg-color="#457BA3" />
      <Range min="60000"    max="65000"     fg-color="#88EE43" />
      <Range min="65000"    max="70000"     fg-color="#457BA3" />
      <Range min="70000"    max="75000"     fg-color="#457BA3" />
      <Range min="75000"    max="80000"     fg-color="#457BA3" />
      <Range min="80000"    max="85000"     fg-color="#457BA3" />
      <Range min="85000"    max="90000"     fg-color="#457BA3" />
      <Range min="90000"    max="95000"     fg-color="#457BA3" />
      <Range min="95000"    max="100000"    fg-color="#457BA3" />
    </MeasureRange>
    <MeasureRange name="[Measures].[Store Sqft]">
      <Range min="0"      max="50000"     fg-color="#fff7ec" />
      <Range min="50000"    max="100000"    fg-color="#fee8c8" />
      <Range min="100000"   max="150000"    fg-color="#fdd49e" />
      <Range min="150000"   max="200000"    fg-color="#fdbb84" />
      <Range min="200000"   max="250000"    fg-color="#fc8d59" />
      <Range min="250000"   max="300000"    fg-color="#ef6548" />
      <Range min="300000"   max="350000"    fg-color="#d7301f" />
      <Range min="350000"   max="400000"    fg-color="#b30000" />
      <Range min="400000"   max="450000"    fg-color="#7f0000" />
      <Range min="500000"   max="550000"    fg-color="#640000" />
      <Range min="550000"   max="600000"    fg-color="#4A0000" />
    </MeasureRange>
    <MeasureRange name="[Measures].[Grocery Sqft]">
      <Range min="0"      max="50000"     fg-color="#fff7ec" />
      <Range min="50000"    max="100000"    fg-color="#fee8c8" />
      <Range min="100000"   max="150000"    fg-color="#fdd49e" />
      <Range min="150000"   max="200000"    fg-color="#fdbb84" />
      <Range min="200000"   max="250000"    fg-color="#fc8d59" />
      <Range min="250000"   max="300000"    fg-color="#ef6548" />
      <Range min="300000"   max="350000"    fg-color="#d7301f" />
      <Range min="350000"   max="400000"    fg-color="#b30000" />
      <Range min="400000"   max="450000"    fg-color="#7f0000" />
      <Range min="500000"   max="550000"    fg-color="#640000" />
      <Range min="550000"   max="600000"    fg-color="#4A0000" />
    </MeasureRange>
  </MeasureRanges>
</Schema>

This schema contains various cubes (Sales,Warehouse,Store,etc.). Each cube has its own dimensions and measures defined, but users have the option to create shared dimensions for all cubes. These are the first part of the schema created, before the cubes themselves have been defined.

This example uses more complex dimensions and measures with SQL statements. The last part of the schema also defines its own code. This code establishes equivalencies between schema tables and tables with geometric dimensions, for mapping purposes.

Copy
<Geometry name="Store country (geom)" table="geo_countries" primaryKey="id_country">
    <Table name="store" columns="store_country" />
</Geometry>

Finally, using the Measure Range tag, we can set the map to display quantity ranges with different colors.

Copy
<MeasureRange name="[Measures].[Grocery Sqft]">
    <Range min="0"      max="50000"     fg-color="#fff7ec" />
    <Range min="50000"    max="100000"    fg-color="#fee8c8" />
    <Range min="100000"   max="150000"    fg-color="#fdd49e" />
    <Range min="150000"   max="200000"    fg-color="#fdbb84" />
    <Range min="200000"   max="250000"    fg-color="#fc8d59" />
    <Range min="250000"   max="300000"    fg-color="#ef6548" />
    <Range min="300000"   max="350000"    fg-color="#d7301f" />
    <Range min="350000"   max="400000"    fg-color="#b30000" />
    <Range min="400000"   max="450000"    fg-color="#7f0000" />
    <Range min="500000"   max="550000"    fg-color="#640000" />
    <Range min="550000"   max="600000"    fg-color="#4A0000" />
</MeasureRange>

Using the schema application, the following analysis is generated for the Sales cube:

5 Example: Numerical Formats

This example shows how to test the number formatting of Measures, using the standard attribute formatString.

Consider the following OLAP Schema:

Copy
<?xml version="1.0"?>
<Schema name="Numeric formatting">
	<Dimension name="Dimension Key">
		<Hierarchy hasAll="true">
            <Table name="numeric_example" />
            <Level name="Column key" column="col_key" uniqueMembers="true" />
		</Hierarchy>
	</Dimension>
    <Cube name="Cube Integer" defaultMeasure="Measure Smallint">
        <Table name="numeric_example" />
        <DimensionUsage name="Dimension Key"    source="Dimension Key"/>
        <Measure name="Integer No-format"       column="col_integer" aggregator="sum" />
        <Measure name="Integer General-Number"  column="col_integer" aggregator="sum" formatString="General Number" />
        <Measure name="Integer xcxxxp000"       column="col_integer" aggregator="sum" formatString="#,###.000" />
        <Measure name="Integer 0"               column="col_integer" aggregator="sum" formatString="0" />
    </Cube>
	<Cube name="Cube Decimal" defaultMeasure="Measure Smallint">
        <Table name="numeric_example" />
        <DimensionUsage name="Dimension Key"    source="Dimension Key"/>
        <Measure name="Decimal No-format"       column="col_decimal" aggregator="sum" />
        <Measure name="Decimal General-Number"  column="col_decimal" aggregator="sum" formatString="General Number" />
        <Measure name="Decimal Percent"         column="col_decimal" aggregator="sum" formatString="Percent" />
        <Measure name="Decimal Scientific"      column="col_decimal" aggregator="sum" formatString="Scientific" />
        <Measure name="Decimal xcxxxp00"        column="col_decimal" aggregator="sum" formatString="#,###.00" />
        <Measure name="Decimal xcxxx"           column="col_decimal" aggregator="sum" formatString="#,###" />
        <Measure name="Decimal 0"               column="col_decimal" aggregator="sum" formatString="0" />
    </Cube>
</Schema>

In order to use it, the following tables and data should be in the database:

Copy
!DROP TABLE numeric_example;
CREATE TABLE numeric_example ( col_key CHAR(12) PRIMARY KEY,
    col_smallint SMALLINT,      col_integer INTEGER,  col_bigint BIGINT,      
    col_decimal DECIMAL(14,8),  col_real REAL,        col_double DOUBLE PRECISION );
INSERT INTO numeric_example VALUES ( 'Reg 11', 11, 22, 33, 456.78912345, 66.77, 88.9876543 );
INSERT INTO numeric_example values ( 'Reg 22', 22, 44556677, 33221100, 87456.78912345, 334466.77, 112288.9876543 );

Consider the following OLAP query against the Cube Decimal. See how decimals are displayed due to the formatstring tag:

Consider the following OLAP query agianst the Cube Integer. See how integers are displayed due to the formatstring tag:

6 Example: Automatic Aliases in Tables

This example shows the usage of the alias attribute of the Table tag. Let's consider the following cube:

Copy
<!-- =============================================================== -->
<!-- == CUSTOM TEST: TABLE ALIAS                                  == -->
<!-- =============================================================== -->
<Cube name="Test_Alias2" useLeftJoins="true">
	<Table name="sales_fact_1997"/>
    <Dimension name="Product" foreignKey="product_id">
        <Hierarchy hasAll="true" primaryKey="product_id" primaryKeyTable="product">
            <Join leftKey="product_class_id" rightKey="product_class_id">
                <Table name="product"/>
                <Table name="product_class"/>
            </Join>
            <Level name="Product Family" table="product_class" column="product_family" uniqueMembers="true"/>
        </Hierarchy>
        <Hierarchy name="Product brand" hasAll="true" primaryKey="product_id" primaryKeyTable="product">
            <Table name="product" alias="product_2" />
            <Level name="Brand Name" column="brand_name"   uniqueMembers="false" />
        </Hierarchy>
    </Dimension>
   	<Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="##,###" />
</Cube>

Consider the OLAP query:

The SQL query performed is:

Copy
SELECT product_class.product_family, product_2.brand_name, sum(sales_fact_1997.unit_sales) unit_sales_m1
  FROM sales_fact_1997
  LEFT JOIN product ON sales_fact_1997.product_id = product.product_id
  LEFT JOIN product_class ON product.product_class_id = product_class.product_class_id
  LEFT JOIN product product_2 ON sales_fact_1997.product_id = product_2.product_id
GROUP BY product_class.product_family, product_2.brand_name
ORDER BY product_class.product_family, product_2.brand_name

This cube has two different dimensions with hierarchies. Both dimensions contain different tables but two of them use the same table name "product". To avoid that a query only reports about one of the tables that use the same name, it is necessary to create an alias to one of these tables, in this case "product_2".

7 Example: preventing Division by Zero

This example aims to provide solutions for issues caused by division by zero (in the database engine). Division by zero errors may occur if calculated measures are used. Let's consider the following cube:

Copy
<!-- =============================================================== -->
<!-- == CUSTOM TEST: Division by zero                             == -->
<!-- =============================================================== -->
<Cube name="Test_DIV_BY_ZERO" useLeftJoins="true">
	<Table name="sales_fact_1997" />
	<Dimension name="Dim" foreignKey="product_id">
		<Hierarchy hasAll="true" primaryKey="product_id" primaryKeyTable="product">
			<Table name="product"/>
			<Level name="ProductID" table="product" column="product_id" uniqueMembers="true"/>
		</Hierarchy>
	</Dimension>
	<Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="##,###" />
	<CalculatedMember name="Test ERROR" dimension="Measures"  formatString="#,###.00">
		<Formula>[Measures].[Unit Sales] / ([Measures].[Unit Sales] - [Measures].[Unit Sales])</Formula>
	</CalculatedMember>
	<CalculatedMember name="Test OK" dimension="Measures"  formatString="#,###.00">
		<Formula>[Measures].[Unit Sales] / olap_nullifzero([Measures].[Unit Sales] - [Measures].[Unit Sales])</Formula>
	</CalculatedMember>
</Cube>

Any query using the OLAP client which involves the measure "Test ERROR" will end with an error message ("division by zero in the database engine"). Therefore, the same situation may occur in a real schema used to calculate discounts, growth rate, etc.

One possible solution is to use a measure such as "Test OK" in the previous cube, where the following SPL function should also be catalogued in the database object dictionary:

Copy
<!-- =============================================================================  -->
<!--                                                                                -->
<!--    olap_nullifzero (p_num)                                                     -->
<!--                                                                                -->
<!--    Return NULL if the past numerical parameter is zero.                        -->
<!--                                                                                -->
<!--    Used in OLAP schemas to prevent division by zero in                         -->
<!--    calculated measures (discounts, etc.).                                      -->
<!--                                                                                --> 
<!-- =============================================================================  -->
<function name='olap_nullifzero'>
    <test>
        <unit id='1'>
            select (45 / olap_nullifzero(0)) from cdataemp;
        </unit>
    </test>
    <args>
        <arg name='p_num' type='decimal' size='14,3' />
    </args>
    <returns type='decimal' size='14,3' />
    <body>
        <if>
            <expr>p_num = 0</expr>
            <then>
                <return>NULL</return>
            </then>
        </if>
        <return>p_num</return>
    </body>
</function>
 

8 Example: schema defined by a view table

This example shows how to create a schema using a view table. The complex schemes, those where we have to combine more than two tables, should be built using a view.

In a database, a view is the result set of a stored query on the data, which the database users can query just as they would in a persistent database collection object. This pre-established query command is kept in the physical dictionary/catalog wic_table_object. Views have the same structure as a table: rows and columns.

  • In the first place, the view should be defined in the wic_table_object of the dictionary. In this case, a view table named ccossalc_cpresalc_v.
    Copy
    <view name='ccossalc_cpresalc_v'>
        <columns>
            empcode, empname,
            proyec, nompro,
            seccio, nomsec,
            cuenta, nombre,
            placon, descri,
            ejerci,
            period,
            dimcode1,
            dimcode2,
            sal_debe,
            sal_haber,
            pre_debe,
            pre_haber
        </columns>
        <select>
            <columns>
                ccossalc.empcode, cempresa.empname,
                ccossalc.proyec, cproyect.nompro,
                ccossalc.seccio, cseccion.nomsec,
                ccossalc.cuenta, ccuentas.nombre,
                ccossalc.placon, cplacont.descri,
                ccossalc.ejerci,
                ccossalc.period,
                ccossalc.dimcode1,
                ccossalc.dimcode2,
                ccossalc.debe sal_debe,
                ccossalc.haber sal_haber,
                cpresalc.debe pre_debe,
                cpresalc.haber pre_haber
            </columns>
            <from table='ccossalc' >
                <join type='left' table='cpresalc'>
                  <on>ccossalc.empcode = cpresalc.empcode</on>
                  <on>ccossalc.ejerci  = cpresalc.ejerci</on>
                  <on>ccossalc.period  = cpresalc.period</on>
                </join>
                <join type="left" table="cempresa">
                  <on>ccossalc.empcode = cempresa.empcode</on>
                </join>
                <join type='left' table='cproyect'>
                  <on>ccossalc.proyec = cproyect.codigo</on>
                </join>
                <join type='left' table='cseccion'>
                  <on>ccossalc.seccio = cseccion.codigo</on>
                </join>
                <join type='left' table='cplacont'>
                  <on>ccossalc.placon = cplacont.codigo</on>
                </join>      
                <join type='left' table='ccuentas'>
                  <on>ccossalc.placon = ccuentas.placon</on>
                  <on>ccossalc.cuenta = ccuentas.codigo</on>
                </join>
            </from>
        </select>
    </view>
  • In the second place, it is necessary to build the Olap schema (in this case, SaldosCostesPresP) and point in it to the previous view ccossalc_cpresalc_v:
    Copy
    <?xml version="1.0"?>
    <Schema name="SaldosCostesPresP">
        
            <!-- Saldos de costes comparados con presupuesto de costes -->
            
    
        	<Dimension name="Fecha">
    			<Hierarchy hasAll="true">
    				<Table name="ccossalc_cpresalc_v"/>
    			    <Level name="Ejercicio" column="ejerci" uniqueMembers="true"    />
    			    <Level name="Periodo"   column="period" uniqueMembers="true"   />
    			</Hierarchy>
    		</Dimension>
    	
        	<Dimension name="Empresa">
        	    <Hierarchy hasAll="true" allMemberName="Todas las empresas">
        	        <Table name="ccossalc_cpresalc_v"/>
        	        <Level name="Código empresa" column="empcode" uniqueMembers="true" />
        	        <Level name="Nombre empresa" column="empname" uniqueMembers="false" />
        	    </Hierarchy>
        	</Dimension>
    	
        	<Dimension name="Proyecto" foreignKey="proyec">
    			<Hierarchy hasAll="true" allMemberName="Todos los proyectos" primaryKey="codigo">
    				<Table name="ccossalc_cpresalc_v"/>
    				<Level name="Código proyecto" column="proyec" uniqueMembers="true"/>
    				<Level name="Nombre proyecto" column="nompro" uniqueMembers="false"/>
    			</Hierarchy>
    		</Dimension>
    	
        	<Dimension name="Sección" foreignKey="seccio">
    			<Hierarchy hasAll="true" allMemberName="Todas las secciones" primaryKey="codigo">
    				<Table name="ccossalc_cpresalc_v"/>
    				<Level name="Código sección" column="seccio" uniqueMembers="true"/>
    				<Level name="Nombre sección" column="nomsec" uniqueMembers="false"/>
    			</Hierarchy>
    		</Dimension>
    	
    		<Dimension name="Dimensión 1">
    			<Hierarchy hasAll="true">
    				<Table name="ccossalc_cpresalc_v"/>
    				<Level name="Dimensión 1" column="dimcode1" uniqueMembers="true" />
    			</Hierarchy>
    		</Dimension>
    		<Dimension name="Dimensión 2">
    			<Hierarchy hasAll="true">
    				<Table name="ccossalc_cpresalc_v"/>
    				<Level name="Dimensión 2" column="dimcode2" uniqueMembers="true" />
    			</Hierarchy>
    		</Dimension>
    	
        	<Dimension name="Cuenta local" foreignKey="placon,cuenta">
    			<Hierarchy hasAll="true" primaryKey="placon,codigo">
    				<Table name="ccossalc_cpresalc_v"/>
    				<Level name="Código cuenta" column="cuenta" uniqueMembers="true"/>
    				<Level name="Nombre cuenta" column="nombre" uniqueMembers="false"/>
    			</Hierarchy>
    		</Dimension>
    		<Dimension name="Niveles">
    			<Hierarchy hasAll="true">
    				<Table name="ccossalc_cpresalc_v"/>
    				<Level name="Nivel 1" column="cuenta" uniqueMembers="true">
    				  <KeyExpression>
    					<SQL dialect="generic">SUBSTR(cuenta, 1, 1)</SQL>
    				  </KeyExpression>
    				</Level>
    				<Level name="Nivel 2" column="cuenta" uniqueMembers="true">
    				  <KeyExpression>
    					<SQL dialect="generic">SUBSTR(cuenta, 1, 2)</SQL>
    				  </KeyExpression>
    				</Level>
    				<Level name="Nivel 3" column="cuenta" uniqueMembers="true">
    				  <KeyExpression>
    					<SQL dialect="generic">SUBSTR(cuenta, 1, 3)</SQL>
    				  </KeyExpression>
    				</Level>
    				<Level name="Nivel 4" column="cuenta" uniqueMembers="true">
    				  <KeyExpression>
    					<SQL dialect="generic">SUBSTR(cuenta, 1, 4)</SQL>
    				  </KeyExpression>
    				</Level>
    			</Hierarchy>
    		</Dimension>
    
        <Cube name="Costes y Presupuestado">
            <Table name="ccossalc_cpresalc_v" />
    
            <DimensionUsage name= 'Fecha'          source = 'Fecha' />
            <DimensionUsage name= 'Empresa'        source = 'Empresa' />
            <DimensionUsage name= 'Proyecto'       source = 'Proyecto' />
            <DimensionUsage name= 'Sección'        source = 'Sección' />
            <DimensionUsage name= 'Dimensión 1'    source = 'Dimensión 1' />
            <DimensionUsage name= 'Dimensión 2'    source = 'Dimensión 2' />
            <DimensionUsage name= 'Cuenta local'   source = 'Cuenta local' />
            <DimensionUsage name= 'Niveles'        source = 'Niveles' />
    
        	<Measure name="Costes" aggregator="sum" formatString="#,###.00">
    			<MeasureExpression>
    				<SQL dialect="oracle">(sal_debe - sal_haber)</SQL>
    				<SQL dialect="generic">(sal_debe - sal_haber)</SQL>
    			</MeasureExpression>
    		</Measure>
    		<Measure name="Costes Presupuestados" aggregator="sum" formatString="#,###.00">
    			<MeasureExpression>
    				<SQL dialect="oracle">(pre_debe - pre_haber)</SQL>
    				<SQL dialect="generic">(pre_debe - pre_haber)</SQL>
    			</MeasureExpression>
    		</Measure>
            <Measure name="Debe Coste"             column="sal_debe"                 aggregator="sum"    formatString="#,##.00"  />
            <Measure name="Haber Coste"            column="sal_haber"                aggregator="sum"    formatString="#,##.00"  />
            <Measure name="Debe Presupuestado"     column="pre_debe"                 aggregator="sum"    formatString="#,##.00"  />
            <Measure name="Haber Presupuestado"    column="pre_haber"                aggregator="sum"    formatString="#,##.00"  />
        </Cube>
    </Schema>

As a result, we have created an Olap schema in a simpliest way.