Перевод запроса T-SQL в MDX - PullRequest
0 голосов
/ 19 ноября 2018

Я новый пользователь 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

Код ниже - это то, что я придумал. Кажется очень неуклюжим и через 2 минуты возвращает данные и не корректен.

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 голосов
/ 22 ноября 2018

Насколько я понимаю, вы хотите, чтобы объем продаж и количество отдельных клиентов для продуктов и их подкатегорий были в пределах диапазона данных.Эти продукты и их подкатегории были куплены клиентами, которые купили товары из подкатегорий 1 и 2 в течение того же периода.Для этого вы сначала взяли список клиентов во временной таблице, затем для всех продуктов, купленных этими клиентами, вы сгруппировали продажи продуктов и подсчитали количество клиентов.

Теперь есть пара проблем.1) MDX не поддерживает подзапрос.Таким образом, у вас нет простого способа собрать список клиентов, который вы указали в SQL.

2) В MDX нельзя разместить один атрибут измерения на двух осях.Переводя это на вашу проблему, вы хотите провести перекрестный анализ всех продаж продуктов по сравнению с двумя продуктами (анализ корзины рынка).Поэтому в идеале в MDX решение должно заключаться в том, чтобы поместить одинаковый атрибут измерения на обе оси, но это не поддерживается.

3) В вашем запросе SQL вы используете только фактические продажи через Интернет, в MDX вытакже используют [Показатели]. [Объем продаж], который не относится к продажам через Интернет

4) Причина повторения 18484 состоит в том, что набор не знает о контексте запроса.Проще говоря, для строки 1 набор не знает, что он выполняет для комбинации 3, 560

...