Daanse Tutorial - Aggregation Aggregate Tables
This tutorial discusses TableQuery with AggregationExclude. AggregationExclude defines exclusion rules that prevent specific tables from being used as aggregation tables, even if they would otherwise match aggregation patterns or be considered suitable for aggregation optimization. AggregationExclude is essential for maintaining aggregation accuracy and system reliability by providing explicit control over which tables should be avoided during aggregation table discovery and selection.
Database Schema
The cube defined in this example is based on
SALES_FACT_1997
table which contains two columns:PRODUCT_ID
andSTORE_COST
.PRODUCT
table which contains 4 columns:PRODUCT_CLASS_ID
,PRODUCT_ID
,brand_name
,product_name
PRODUCT_CLASS
table which contains 3 columns:PRODUCT_CLASS_ID
,PRODUCT_ID
andbrand_name
.AGG_C_SPECIAL_SALES_FACT_1997
table which contains 3 columns:PRODUCT_ID
,STORE_COST_SUM
,FACT_COUNT
;AGG_C_14_SALES_FACT_1997
this is exclude tableAGG_LC_100_SALES_FACT_1997
this is exclude table
<roma:DatabaseSchema id="_databaseSchema_AggregateTables">
<tables xsi:type="roma:PhysicalTable" id="_table_sales_fact_1997" name="SALES_FACT_1997">
<columns xsi:type="roma:PhysicalColumn" id="_column_sales_fact_1997_product_id" name="PRODUCT_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_sales_fact_1997_store_cost" name="STORE_COST" type="Decimal" columnSize="10" decimalDigits="4"/>
</tables>
<tables xsi:type="roma:PhysicalTable" id="_table_product" name="PRODUCT">
<columns xsi:type="roma:PhysicalColumn" id="_column_product_product_class_id" name="PRODUCT_CLASS_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_product_product_id" name="PRODUCT_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_product_brandName" name="brand_name" columnSize="60"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_product_productName" name="product_name" columnSize="60"/>
</tables>
<tables xsi:type="roma:PhysicalTable" id="_table_product_class" name="PRODUCT_CLASS">
<columns xsi:type="roma:PhysicalColumn" id="_column_product_class_product_class_id" name="PRODUCT_CLASS_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_product_class_product_famile" name="PRODUCT_FAMILE" columnSize="60"/>
</tables>
<tables xsi:type="roma:PhysicalTable" id="_table_agg_c_special_sales_fact_1997" name="AGG_C_SPECIAL_SALES_FACT_1997">
<columns xsi:type="roma:PhysicalColumn" id="_column_agg_c_special_sales_fact_1997_product_id" name="PRODUCT_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_agg_c_special_sales_fact_1997_store_cost_sum" name="STORE_COST_SUM" type="Decimal" columnSize="10" decimalDigits="4"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_agg_c_special_sales_fact_1997_fact_count" name="FACT_COUNT" type="Integer"/>
</tables>
<tables xsi:type="roma:PhysicalTable" id="_table_agg_c_14_sales_fact_1997" name="AGG_C_14_SALES_FACT_1997"/>
<tables xsi:type="roma:PhysicalTable" id="_table_agg_lc_100_sales_fact_1997" name="AGG_LC_100_SALES_FACT_1997"/>
</roma:DatabaseSchema>
Note: This is only a symbolic example. For the exact definition, see the Definition section.
Query
The bridge between the cube and the database is the query element. In this case, it is a TableQuery, as it directly references the physical table SALES_FACT_1997
. The query element is not visible to users accessing the cube through the XMLA API, such as Daanse Dashboard, Power BI, or Excel. this TableQuery have one AggregationTable with reference to 'AGG_C_SPECIAL_SALES_FACT_1997' the specific database table that contains the pre-computed aggregation data. this tabele will use for calculate aggregation data for aggregationMeasure [Measures].[Store Cost] for level [Product].[Product Family].[Product Family].
<roma:TableQuery id="_query_salesFact1997Query" aggregationTables="roma:AggregationName _aggregationName_AGG_C_SPECIAL_SALES_FACT_1997" table="_table_sales_fact_1997">
<aggregationExcludes name="AGG_C_14_SALES_FACT_1997"/>
<aggregationExcludes name="AGG_LC_100_SALES_FACT_1997"/>
</roma:TableQuery>
Note: This is only a symbolic example. For the exact definition, see the Definition section.
Product Query
The TableQuery for the PRODUCT table.
<roma:TableQuery id="_query_productQuery" table="_table_product"/>
Note: This is only a symbolic example. For the exact definition, see the Definition section.
Product Class Query
The TableQuery for the PRODUCT_CLASS table.
<roma:TableQuery id="_query_productClassQuery" table="_table_product_class"/>
Note: This is only a symbolic example. For the exact definition, see the Definition section.
Product Class Query
The JoinQuery specifies which TableQueries should be joined. It also defines the columns in each table that are used for the join:
- In the PRODUCT the join uses the foreign key.
- In the PRODUCT_CLASS table, the join uses the primary key.
<roma:JoinQuery id="_joinQuery_productClassProduct">
<left key="_column_product_product_class_id" query="_query_productQuery"/>
<right key="_column_product_class_product_class_id" query="_query_productClassQuery"/>
</roma:JoinQuery>
Note: This is only a symbolic example. For the exact definition, see the Definition section.
Level - Product Family
The Level Product Family uses the column attribute to specify the primary key column PRODUCT_FAMILE from table PRODUCT_CLASS.
<roma:Level id="_level_Product_Family_Level" name="Product Family" column="_column_product_class_product_famile"/>
Note: This is only a symbolic example. For the exact definition, see the Definition section.
Hierarchy
This hierarchy consists the level Product Family.
- The primaryKey attribute specifies the column that contains the primary key of the hierarchy.
- The query attribute references the Join-query used to retrieve the data for the hierarchy.
<roma:ExplicitHierarchy id="_hierarchy_Product_Family_Hierarchy" name="Product Family" displayFolder="Details" primaryKey="_column_product_product_id" query="_joinQuery_productClassProduct" levels="_level_Product_Family_Level"/>
Note: This is only a symbolic example. For the exact definition, see the Definition section.
Dimension
The Dimension has only one hierarchy.
<roma:StandardDimension id="_dimension_ProductDimension" name="Product" hierarchies="roma:ExplicitHierarchy _hierarchy_Product_Family_Hierarchy"/>
Note: This is only a symbolic example. For the exact definition, see the Definition section.
Cube, MeasureGroup and Measure
The cube is the element visible to users in analysis tools. A cube is based on elements such as measures, dimensions, hierarchies, KPIs, and named sets. In this case, we only define measures, which are the minimal required elements. The other elements are optional. To link a measure to the cube, we use the MeasureGroup
element. The MeasureGroup
is useful for organizing multiple measures into logical groups. Measures are used to define the data that should be aggregated. In this example, the measure is named Store Cost and references the STORE_COST
column in the SALES_FACT_1997 table. But fact table query has AggregationTable 'AGG_C_SPECIAL_SALES_FACT_1997'. The aggregation calculation will use AGG_C_SPECIAL_SALES_FACT_1997 table instead of SALES_FACT_1997. The measure is aggregated using summation.
<roma:PhysicalCube id="_cube_Sales" name="Sales" query="_query_salesFact1997Query">
<dimensionConnectors foreignKey="roma:PhysicalColumn _column_sales_fact_1997_product_id" dimension="roma:StandardDimension _dimension_ProductDimension" overrideDimensionName="Product" id="_dimensionConnector_product"/>
<measureGroups>
<measures xsi:type="roma:SumMeasure" id="_measure_StoreCost" name="Store Cost" formatString=",###.00" column="_column_sales_fact_1997_store_cost"/>
</measureGroups>
</roma:PhysicalCube>
Note: This is only a symbolic example. For the exact definition, see the Definition section.
Definition
This files represent the complete definition of the catalog.
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:roma="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping">
<roma:AggregationName id="_aggregationName_AGG_C_SPECIAL_SALES_FACT_1997" name="_table_agg_c_special_sales_fact_1997">
<aggregationFactCount column="_column_agg_c_special_sales_fact_1997_fact_count"/>
<aggregationMeasures column="_column_agg_c_special_sales_fact_1997_store_cost_sum" name="[Measures].[Store Cost]"/>
<aggregationLevels column="_column_product_class_product_famile" name="[Product].[Product Family].[Product Family]"/>
</roma:AggregationName>
<roma:Catalog description="Aggregate table optimization techniques" name="Daanse Tutorial - Aggregation Aggregate Tables" cubes="_cube_Sales" dbschemas="_databaseSchema_AggregateTables"/>
<roma:DatabaseSchema id="_databaseSchema_AggregateTables">
<tables xsi:type="roma:PhysicalTable" id="_table_sales_fact_1997" name="SALES_FACT_1997">
<columns xsi:type="roma:PhysicalColumn" id="_column_sales_fact_1997_product_id" name="PRODUCT_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_sales_fact_1997_store_cost" name="STORE_COST" type="Decimal" columnSize="10" decimalDigits="4"/>
</tables>
<tables xsi:type="roma:PhysicalTable" id="_table_product" name="PRODUCT">
<columns xsi:type="roma:PhysicalColumn" id="_column_product_product_class_id" name="PRODUCT_CLASS_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_product_product_id" name="PRODUCT_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_product_brandName" name="brand_name" columnSize="60"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_product_productName" name="product_name" columnSize="60"/>
</tables>
<tables xsi:type="roma:PhysicalTable" id="_table_product_class" name="PRODUCT_CLASS">
<columns xsi:type="roma:PhysicalColumn" id="_column_product_class_product_class_id" name="PRODUCT_CLASS_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_product_class_product_famile" name="PRODUCT_FAMILE" columnSize="60"/>
</tables>
<tables xsi:type="roma:PhysicalTable" id="_table_agg_c_special_sales_fact_1997" name="AGG_C_SPECIAL_SALES_FACT_1997">
<columns xsi:type="roma:PhysicalColumn" id="_column_agg_c_special_sales_fact_1997_product_id" name="PRODUCT_ID" type="Integer"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_agg_c_special_sales_fact_1997_store_cost_sum" name="STORE_COST_SUM" type="Decimal" columnSize="10" decimalDigits="4"/>
<columns xsi:type="roma:PhysicalColumn" id="_column_agg_c_special_sales_fact_1997_fact_count" name="FACT_COUNT" type="Integer"/>
</tables>
<tables xsi:type="roma:PhysicalTable" id="_table_agg_c_14_sales_fact_1997" name="AGG_C_14_SALES_FACT_1997"/>
<tables xsi:type="roma:PhysicalTable" id="_table_agg_lc_100_sales_fact_1997" name="AGG_LC_100_SALES_FACT_1997"/>
</roma:DatabaseSchema>
<roma:TableQuery id="_query_productClassQuery" table="_table_product_class"/>
<roma:TableQuery id="_query_productQuery" table="_table_product"/>
<roma:TableQuery id="_query_salesFact1997Query" aggregationTables="_aggregationName_AGG_C_SPECIAL_SALES_FACT_1997" table="_table_sales_fact_1997">
<aggregationExcludes name="AGG_C_14_SALES_FACT_1997"/>
<aggregationExcludes name="AGG_LC_100_SALES_FACT_1997"/>
</roma:TableQuery>
<roma:JoinQuery id="_joinQuery_productClassProduct">
<left key="_column_product_product_class_id" query="_query_productQuery"/>
<right key="_column_product_class_product_class_id" query="_query_productClassQuery"/>
</roma:JoinQuery>
<roma:Level id="_level_Product_Family_Level" name="Product Family" column="_column_product_class_product_famile"/>
<roma:ExplicitHierarchy id="_hierarchy_Product_Family_Hierarchy" name="Product Family" displayFolder="Details" primaryKey="_column_product_product_id" query="_joinQuery_productClassProduct" levels="_level_Product_Family_Level"/>
<roma:StandardDimension id="_dimension_ProductDimension" name="Product" hierarchies="_hierarchy_Product_Family_Hierarchy"/>
<roma:PhysicalCube id="_cube_Sales" name="Sales" query="_query_salesFact1997Query">
<dimensionConnectors foreignKey="_column_sales_fact_1997_product_id" dimension="_dimension_ProductDimension" overrideDimensionName="Product" id="_dimensionConnector_product"/>
<measureGroups>
<measures xsi:type="roma:SumMeasure" id="_measure_StoreCost" name="Store Cost" formatString="#,###.00" column="_column_sales_fact_1997_store_cost"/>
</measureGroups>
</roma:PhysicalCube>
</xmi:XMI>
Tutorial Zip
This files contaisn the data-tables as csv and the mapping as xmi file.