How to create MDX queries in R using olapR
Applies to: SQL Server 2016 (13.x) and later versions
The olapR in SQL Server Machine Learning Services package supports MDX queries against cubes hosted in SQL Server Analysis Services. You can build a query against an existing cube, explore dimensions and other cube objects, and paste in existing MDX queries to retrieve data.
This article describes the two main uses of the olapR package:
- Build an MDX query from R, using the constructors provided in the olapR package
- Execute an existing, valid MDX query using olapR and an OLAP provider
The following operations are not supported:
- DAX queries against a tabular model
- Creation of new OLAP objects
- Writeback to partitions, including measures or sums
Build an MDX query from R
Define a connection string that specifies the OLAP data source (SSAS instance), and the MSOLAP provider.
Use the function
OlapConnection(connectionString)
to create a handle for the MDX query and pass the connection string.Use the
Query()
constructor to instantiate a query object.Use the following helper functions to provide more details about the dimensions and measures to include in the MDX query:
cube()
Specify the name of the SSAS database. If connecting to a named instance, provide the machine name and instance name.columns()
Provide the names of the measures to use in the ON COLUMNS argument.rows()
Provide the names of the measures to use in the ON ROWS argument.slicers()
Specify a field or members to use as a slicer. A slicer is like a filter that is applied to all MDX query data.axis()
Specify the name of an additional axis to use in the query.An OLAP cube can contain up to 128 query axes. Generally, the first four axes are referred to as Columns, Rows, Pages, and Chapters.
If your query is relatively simple, you can use the functions
columns
,rows
, etc. to build your query. However, you can also use theaxis()
function with a non-zero index value to build an MDX query with many qualifiers, or to add extra dimensions as qualifiers.
Pass the handle, and the completed MDX query, into one of the following functions, depending on the shape of the results:
executeMD
Returns a multi-dimensional arrayexecute2D
Returns a two-dimensional (tabular) data frame
Execute a valid MDX query from R
Define a connection string that specifies the OLAP data source (SSAS instance), and the MSOLAP provider.
Use the function
OlapConnection(connectionString)
to create a handle for the MDX query and pass the connection string.Define an R variable to store the text of the MDX query.
Pass the handle and the variable containing the MDX query into the functions
executeMD
orexecute2D
, depending on the shape of the results.executeMD
Returns a multi-dimensional arrayexecute2D
Returns a two-dimensional (tabular) data frame
Examples
The following examples are based on the AdventureWorks data mart and cube project, because that project is widely available, in multiple versions, including backup files that can easily be restored to Analysis Services. If you don't have an existing cube, get a sample cube using either of these options:
Create the cube that is used in these examples by following the Analysis Services tutorial up to Lesson 4: Creating an OLAP cube
Download an existing cube as a backup, and restore it to an instance of Analysis Services. For example, this site provides a fully processed cube in zipped format: Adventure Works Multidimensional Model SQL 2014. Extract the file, and then restore it to your SSAS instance. For more information, see Backup and restore, or Restore-ASDatabase Cmdlet.
1. Basic MDX with slicer
This MDX query selects the measures for count and amount of Internet sales count and sales amount, and places them on the Column axis. It adds a member of the SalesTerritory dimension as a slicer, to filter the query so that only the sales from Australia are used in calculations.
SELECT {[Measures].[Internet Sales Count], [Measures].[InternetSales-Sales Amount]} ON COLUMNS,
{[Product].[Product Line].[Product Line].MEMBERS} ON ROWS
FROM [Analysis Services Tutorial]
WHERE [Sales Territory].[Sales Territory Country].[Australia]
- On columns, you can specify multiple measures as elements of a comma-separated string.
- The Row axis uses all possible values (all MEMBERS) of the "Product Line" dimension.
- This query would return a table with three columns, containing a rollup summary of Internet sales from all countries/regions.
- The WHERE clause specifies the slicer axis. In this example, the slicer uses a member of the SalesTerritory dimension to filter the query so that only the sales from Australia are used in calculations.
To build this query using the functions provided in olapR
cnnstr <- "Data Source=localhost; Provider=MSOLAP; initial catalog=Analysis Services Tutorial"
ocs <- OlapConnection(cnnstr)
qry <- Query()
cube(qry) <- "[Analysis Services Tutorial]"
columns(qry) <- c("[Measures].[Internet Sales Count]", "[Measures].[Internet Sales-Sales Amount]")
rows(qry) <- c("[Product].[Product Line].[Product Line].MEMBERS")
slicers(qry) <- c("[Sales Territory].[Sales Territory Country].[Australia]")
result1 <- executeMD(ocs, qry)
For a named instance, be sure to escape any characters that could be considered control characters in R. For example, the following connection string references an instance OLAP01, on a server named ContosoHQ:
cnnstr <- "Data Source=ContosoHQ\\OLAP01; Provider=MSOLAP; initial catalog=Analysis Services Tutorial"
To run this query as a predefined MDX string
cnnstr <- "Data Source=localhost; Provider=MSOLAP; initial catalog=Analysis Services Tutorial"
ocs <- OlapConnection(cnnstr)
mdx <- "SELECT {[Measures].[Internet Sales Count], [Measures].[InternetSales-Sales Amount]} ON COLUMNS, {[Product].[Product Line].[Product Line].MEMBERS} ON ROWS FROM [Analysis Services Tutorial] WHERE [Sales Territory].[Sales Territory Country].[Australia]"
result2 <- execute2D(ocs, mdx)
If you define a query by using the MDX builder in SQL Server Management Studio and then save the MDX string, it will number the axes starting at 0, as shown here:
SELECT {[Measures].[Internet Sales Count], [Measures].[Internet Sales-Sales Amount]} ON AXIS(0),
{[Product].[Product Line].[Product Line].MEMBERS} ON AXIS(1)
FROM [Analysis Services Tutorial]
WHERE [Sales Territory].[Sales Territory Countr,y].[Australia]
You can still run this query as a predefined MDX string. However, to build the same query using R using the axis()
function, you must renumber the axes starting at 1.
2. Explore cubes and their fields on an SSAS instance
You can use the explore
function to return a list of cubes, dimensions, or members to use in constructing your query. This is handy if you don't have access to other OLAP browsing tools, or if you want to programmatically manipulate or construct the MDX query.
To list the cubes available on the specified connection
To view all cubes or perspectives on the instance that you have permission to view, provide the handle as an argument to explore
.
Important
The final result is not a cube; TRUE merely indicates that the metadata operation was successful. An error is thrown if arguments are invalid.
cnnstr <- "Data Source=localhost; Provider=MSOLAP; initial catalog=Analysis Services Tutorial"
ocs <- OlapConnection(cnnstr)
explore(ocs)
Results |
---|
Analysis Services Tutorial |
Internet Sales |
Reseller Sales |
Sales Summary |
[1] TRUE |
To get a list of cube dimensions
To view all dimensions in the cube or perspective, specify the cube or perspective name.
cnnstr <- "Data Source=localhost; Provider=MSOLAP; initial catalog=Analysis Services Tutorial"
ocs \<- OlapConnection(cnnstr)
explore(ocs, "Sales")
Results |
---|
Customer |
Date |
Region |
To return all members of the specified dimension and hierarchy
After defining the source and creating the handle, specify the cube, dimension, and hierarchy to return. In the return results, items that are prefixed with -> represent children of the previous member.
cnnstr <- "Data Source=localhost; Provider=MSOLAP; initial catalog=Analysis Services Tutorial"
ocs <- OlapConnection(cnnstr)
explore(ocs, "Analysis Services Tutorial", "Product", "Product Categories", "Category")
Results |
---|
Accessories |
Bikes |
Clothing |
Components |
-> Assembly Components |
-> Assembly Components |