将T-SQL查询转换为MDX

时间:2018-11-19 17:10:57

标签: ssas mdx mdx-query

我是MDX的新用户。

使用T-SQL可以轻松获得所需的东西,但是事实证明,使用MDX获得等效的东西很困难。

use [AdventureWorksDW2012]

------------------------------------------------------------
--Select customers that purchased specific items during specific time period
------------------------------------------------------------ 
drop table #Customers_Purchased_SelectedProduct
select
distinct 
    a.CustomerKey
into #Customers_Purchased_SelectedProduct
from [dbo].[FactInternetSales] a
    inner join [dbo].[DimProduct] b on a.ProductKey = b.ProductKey
    inner join [dbo].[DimProductSubcategory] c on b.ProductSubcategoryKey = c.ProductSubcategoryKey
where
     a.ShipDateKey between 20050101 and 20081215
    and c.ProductSubcategoryKey in (1 , 2)

------------------------------------------------------------
--Get sales metrics for customers identified above
------------------------------------------------------------ 
select
    c.ProductSubcategoryKey
    , b.ProductKey
    , sum(a.SalesAmount) as SalesAmount
    , count(distinct a.CustomerKey) as 'CustomerDistinct_withPurchases'
from [dbo].[FactInternetSales] a
    inner join [dbo].[DimProduct] b on a.ProductKey = b.ProductKey
    inner join [dbo].[DimProductSubcategory] c on b.ProductSubcategoryKey = c.ProductSubcategoryKey
    inner join #Customers_Purchased_SelectedProduct bb on a.CustomerKey = bb.CustomerKey
where
    a.ShipDateKey between 20050101 and 20081215
    and c.ProductSubcategoryKey not in (1 , 2)
group by 
    c.ProductSubcategoryKey
    , b.ProductKey

下面的代码是我想到的。似乎非常笨拙,两分钟后它返回数据并且不正确。

use [AdventureWorksDW2012]

------------------------------------------------------------
--Select customers that purchased specific items during specific time period
------------------------------------------------------------ 
drop table #Customers_Purchased_SelectedProduct
select
distinct 
    a.CustomerKey
into #Customers_Purchased_SelectedProduct
from [dbo].[FactInternetSales] a
    inner join [dbo].[DimProduct] b on a.ProductKey = b.ProductKey
    inner join [dbo].[DimProductSubcategory] c on b.ProductSubcategoryKey = c.ProductSubcategoryKey
where
     a.ShipDateKey between 20050101 and 20081215
    and c.ProductSubcategoryKey in (1 , 2)

------------------------------------------------------------
--Get sales metrics for customers identified above
------------------------------------------------------------ 
select
    c.ProductSubcategoryKey
    , b.ProductKey
    , sum(a.SalesAmount) as SalesAmount
    , count(distinct a.CustomerKey) as 'CustomerDistinct_withPurchases'
from [dbo].[FactInternetSales] a
    inner join [dbo].[DimProduct] b on a.ProductKey = b.ProductKey
    inner join [dbo].[DimProductSubcategory] c on b.ProductSubcategoryKey = c.ProductSubcategoryKey
    inner join #Customers_Purchased_SelectedProduct bb on a.CustomerKey = bb.CustomerKey
where
    a.ShipDateKey between 20050101 and 20081215
    and c.ProductSubcategoryKey not in (1 , 2)
group by 
    c.ProductSubcategoryKey
    , b.ProductKey
The code below is what I came up with.  Seems extremely clunky and after 2 minutes it returns data and isn't correct.

with

------------------------------------------------------------
----Select customers that purchased specific items during specific time period
------------------------------------------------------------ 
set [Cust] as
nonempty(
            [Dim Customer].[Customer Key].[Customer Key].members ,
            (
                ({[Dim Product].[Product Subcategory Key].&[1] ,[Dim Product].[Product Subcategory Key].&[2]}) ,
                ({[Ship Date].[Date Key].&[20050101]: [Ship Date].[Date Key].&[20081215]}) ,
                [Measures].[Sales Amount]
            )
        )

------------------------------------------------------------
--Create list of subcategories excluding the ones from above
------------------------------------------------------------ 

set [SubCategory Other] as
    except (
                [Dim Product].[Product Subcategory Key].[Product Subcategory Key]
            , ({[Dim Product].[Product Subcategory Key].&[1] ,[Dim Product].[Product Subcategory Key].&[2]})
            )

member [Sales Amount Selected Customers] as sum([Cust] , [Measures].[Sales Amount])
member [Customer Count] as count(nonempty([Cust],[Sales Amount Selected Customers]))

select 
{[Sales Amount Selected Customers] , [Customer Count]} on 0
, ([SubCategory Other] * [Dim Product].[Product Key].[Product Key]) on 1
 from [Adventure Works DW2012]

错误的结果集:

enter image description here

T-SQL查询在不到1秒的时间内运行。我显然搞砸了。

1 个答案:

答案 0 :(得分:0)

我的理解是,您希望在一个数据范围内拥有产品及其子类别的销售额和不同的客户数。这些产品及其子类别由同期购买了子类别1和2的客户购买。为此,您首先要在临时表中获取客户列表,然后针对这些客户购买的所有产品,将产品销售和不同的客户数量分组。

现在有几个问题。 1)MDX不支持子查询。因此,您没有一种直接的方法来收集您在SQL中所做的客户列表。

2)在MDX中,不能在两个轴上放置单个尺寸属性。将此问题转化为您的问题后,您想将所有产品的销售与两个产品进行交叉分析(市场分析)。因此,理想情况下,在MDX中,解决方案应该沿在两个轴上都放置相同的尺寸属性的路线进行,但这是不支持的。

3)在SQL查询中,您仅使用事实互联网销售,在MDX中,您还使用了[度量]。[销售金额]并非来自互联网销售

4)重复18484的原因是该集合不知道查询上下文。简单来说,第1行的集合不知道它正在执行组合3,560