SQL + MDX an Hybrid Query in one Apartment.


Introduction

A common question on MSDN forums is how to write SQL+MDX both in one place.

Examples of such forum posts include

Certain data like aggregated data from MDX Query and then, select detailed data from SQL Query and then get these data in table to show on reports. A couple of the questions were answered on forums but then think it’s better to write article on above topics.

How to Create SQL+MDX Query

Basically to write SQL+MDX combined we have to create link server from where we want data to combine with SQL. To create link server you need to have Admin access to the SQL Server:

IF IS_SRVROLEMEMBER ('sysadmin') = 1

   print 'Current user''s login is a member of the sysadmin role'

ELSE IF IS_SRVROLEMEMBER ('sysadmin') = 0

   print 'Current user''s login is NOT a member of the sysadmin role'

ELSE IF IS_SRVROLEMEMBER ('sysadmin') IS NULL

   print 'ERROR: The server role specified is not valid.'

Above Query returns the whether you have admin admittance to the server or not to create Link Server. More Details on IS_SRVROLEMEMBER (Transact-SQL)

Suppose we have access to the Link server now to get data from created linked server we use another function named as OPENQUERY – Basically OpenQuery function "executes the specified pass-through query on the specified linked server. This server is an OLE DB data source. OPENQUERY can be referenced in the FROM clause of a query as if it were a table name. OPENQUERY can also be referenced as the target table of an INSERT, UPDATE, or DELETE statement. This is subject to the capabilities of the OLE DB provider. Although the query may return multiple result sets, OPENQUERY returns only the first one." [MSDN]

More Details on OPENQUERY (Transact-SQL)

More Details on Hybrid Query

USE
AdventureWorksDW2008R2
GO
EXEC
sp_addlinkedserver
@server='Test',
@srvproduct='',
@provider='MSOLAP',
@datasrc='localhost',
@catalog='Adventure Works DW 2008R2'
 
Declare @MDXExpression as Varchar(MAX)
Select @MDXExpression =
'
SELECT
NON EMPTY
      {
      [Measures].[Sales Amount]
      ,[Measures].[Standard Product Cost]
      ,[Measures].[Tax Amount]
      ,[Measures].[Total Product Cost]
      } ON 0,
NON EMPTY
      {
      [Sales Channel].[Sales Channel].[Sales Channel]
      } ON 1
FROM
      [Adventure Works]
';     
Exec ('SELECT * INTO ##TestTemp FROM OpenQuery(TestTest1,''' + @MDXExpression + ''')')
SELECT
      CONVERT(varchar,t."[Sales Channel].[Sales Channel].[Sales Channel].[MEMBER_CAPTION]") AS  [Date],
      (CONVERT(nvarchar,t."[Measures].[Sales Amount]")) AS [Sales Amount],
      (CONVERT(nvarchar,t."[Measures].[Standard Product Cost]")) AS [Standard Product Cost],
      (CONVERT(nvarchar,t."[Measures].[Tax Amount]")) AS [Tax Amount],
      (CONVERT(nvarchar,t."[Measures].[Total Product Cost]")) AS [Total Product Cost]
from
      ##TestTemp t
 
--DRop Table ##TestTemp

Query Execution

  •       So above query first creates liked server with named as 'Test'.
  •       After that MDX query executed on linked server where we have kept the MDX query in MDXExpression variable.
  •       Using OpenQuery function data gets dump in to ##TestTemp table.
  •       Finally we get the data from ##TestTemp table.