Dax trong USS (Unified star schema)

S? d?ng m? hình USS trong Power BI yêu c?u s? d?ng DAX ph?c t?p h?n so v?i m? hình dimension th?ng th??ng. Tùy vào tr??ng h?p mà ta s? quy?t ??nh vi?t nh? th?: d? hi?u, hi?u n?ng, yêu c?u t?i ?a,... . Th??ng s? có 3 cách: s? d?ng các hàm có h?u t? X ?? truy v?n th?ng qua Bridge, dùng CROSSFILTER ?? ??o chi?u filter Bridge -> Table, TREATAS ?? filter t? Bridge -> table, SUMMARIZE ?? t?o temp table ?? truy v?n (distinctcountx).

Ví d? demo

?? demo t?i s? d?ng AdventureWorksDW Link, load 4 table: FactInternetSale, Date, Product, Customer. R?i Union 4 b?ng này vào Bridge, phan bi?t b?ng c?t Stage.

No alt text provided for this image
m? hình

Kích th??c c?a Dataset trên Power BI Desktop x?p x? 400 Mb (nh? phù h?p ?? demo)

No alt text provided for this image

Các hàm th?ng th??ng s? d?ng

1) Hàm SUM ; ???c s? d?ng nhi?u nh?t trong truy v?n; th??ng dùng ?? tính t?ng giá tr? ??n hàng, t?ng d? n?, ...

Cách 1: truy v?n th?ng qua Bridge


$Sales Amount 1= SUMX(Bridge, RELATED('InternetSales'[SalesAmount]))        

Truy v?n

// DAX Query
DEFINE
??VAR __DS0FilterTable =?
????TREATAS({"M"}, 'Customer'[Gender])

EVALUATE
SUMMARIZECOLUMNS(
??????'Product'[Color],
??????__DS0FilterTable,
??????"v_Order_Sales_Amount", 'InternetSales'[$Sales Amount 1]
????)        

xSQL ???c t?o ra: nhanh ~ 34 ms

No alt text provided for this image

SELECT
'Product'[Color],
SUM ( 'InternetSales'[SalesAmount] )
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
	LEFT OUTER JOIN 'InternetSales' ON 'Bridge'[ KEY InternetSales]='InternetSales'[ KEY InternetSales]
WHERE
	'Customer'[Gender] = 'M';        

Cách 2: truy v?n b?ng CROSSFILTER

$Sales Amount 2 = 
CALCULATE(
SUM('InternetSales'[SalesAmount])
, CROSSFILTER(Bridge[_KEY_InternetSales], InternetSales[_KEY_InternetSales]
,Both
))        

Truy v?n: nh? cách 1

xSQL: Th?i gian ~2s t?o nhi?u b?ng t?m ?? truy v?n bên d??i SE, nh?ng hi?u n?ng t?

No alt text provided for this image
--$TTable3
DEFINE TABLE '$TTable3' := SELECT
'Product'[Color], 'InternetSales'[ KEY InternetSales]
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
	LEFT OUTER JOIN 'InternetSales' ON 'Bridge'[ KEY InternetSales]='InternetSales'[ KEY InternetSales]
WHERE
	'Customer'[Gender] = 'M';

--$TTable4
DEFINE TABLE '$TTable4' := SELECT
SIMPLEINDEXN ( '$TTable3'[InternetSales$ KEY InternetSales] )
FROM '$TTable3';

--$TTable1
DEFINE TABLE '$TTable1' := SELECT
'$TTable3'[Product$Color],
SUM ( '$TTable2'[$Measure0] )
FROM '$TTable2'
	INNER JOIN '$TTable3' ON '$TTable2'[InternetSales$ KEY InternetSales]='$TTable3'[InternetSales$ KEY InternetSales]
REDUCED BY
'$TTable2' := SELECT
'InternetSales'[ KEY InternetSales],
SUM ( 'InternetSales'[SalesAmount] )
FROM 'InternetSales'
WHERE
	'InternetSales'[ KEY InternetSales] ININDEX '$TTable4'[$SemijoinProjection];
        

Cách 3: s? d?ng TREATAS

$Sales Amount 3 =
CALCULATE(
? ? SUM('InternetSales'[SalesAmount])
? ? ,TREATAS( VALUES(Bridge[_KEY_InternetSales]), InternetSales[_KEY_InternetSales])
)         

Truy v?n: nh? cách 1

xSQL: th?i gian ~4s t?o 5 query truy v?n

No alt text provided for this image

2) Hàm DISTINCTCOUNT - > DISTINCTCOUNTX ( ^^ làm gì có): s? d?ng ?? ??m s? l??ng Unique khách hàng, s?n ph?m, ...

Cách 1: tr?c ti?p truy v?n vào Bridge; s? d?ng Stage ?? bi?t mình mu?n ??m d?a vào b?ng nào.

#Customer 1 =
CALCULATE(
? ? DISTINCTCOUNT(Bridge[_KEY_Customer])
? ? ,KEEPFILTERS('Bridge'[Stage] = "InternetSales")
)         

Truy v?n:

// DAX Query
DEFINE
??VAR __DS0FilterTable =?
????TREATAS({"M"}, 'Customer'[Gender])
??VAR __DS0Core =?
????SUMMARIZECOLUMNS('Product'[Color], __DS0FilterTable, "v_Customer_1", 'InternetSales'[#Customer 1])
EVALUATE
??__DS0Core        

xSQL:

No alt text provided for this image

SELECT
'Product'[Color],
DCOUNT ( 'Bridge'[ KEY Customer] )
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
WHERE
	'Customer'[Gender] = 'M' VAND
	'Bridge'[Stage] = 'InternetSales';        

Cách 2: Truy v?n t? Bridge ra b?ng khác

#SalesOrderNumber= 
CALCULATE(
? ? COUNTROWS ( 
? ? ? ? DISTINCT ( 
? ? ? ? ? ? SELECTCOLUMNS ( 
? ? ? ? ? ? ? ? SUMMARIZE(
? ? ? ? ? ? ? ? ? ? 'Bridge',InternetSales[SalesOrderNumber]
? ? ? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? ? ? , "Col"
? ? ? ? ? ? ? ? ? ? , 'InternetSales'[SalesOrderNumber] 
? ? ? ? ? ? ? ? ) 
? ? ? ? ? ? )
? ? ? ? )
,NOT ISBLANK(InternetSales[SalesOrderNumber])
)        

Truy v?n:

DEFIN
??VAR __DS0FilterTable =?
????TREATAS({"M"}, 'Customer'[Gender])

??VAR __DS0Core =?
????SUMMARIZECOLUMNS(
??????'Product'[Color],
??????__DS0FilterTable,
??????"v_SalesOrderNumber_2", 'InternetSales'[#SalesOrderNumber 2]
????)
EVALUATE
??__DS0CoreE        

xSQL:

No alt text provided for this image
SELECT
'Product'[Color],
DCOUNT ( 'InternetSales'[SalesOrderNumber] )
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
	LEFT OUTER JOIN 'InternetSales' ON 'Bridge'[ KEY InternetSales]='InternetSales'[ KEY InternetSales]
WHERE
	'Customer'[Gender] = 'M' VAND
	'InternetSales'[SalesOrderNumber] NIN ( null )         

Cách 3: s? d?ng CROSSFILTER

#SalesOrderNumber 3 =
CALCULATE(
? ? DISTINCTCOUNT(
? ? ? ? 'InternetSales'[SalesOrderNumber]
? ? ),
? ? CROSSFILTER(Bridge[_KEY_InternetSales],InternetSales[_KEY_InternetSales], Both)
)         

Truy v?n: gi?ng cách 2

xSQL: ~3s hi?u n?ng b? gi?m m?nh khi FE t?o ra nhi?u query truy v?n

No alt text provided for this image
SELECT
'Product'[Color], 'InternetSales'[ KEY InternetSales]
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
	LEFT OUTER JOIN 'InternetSales' ON 'Bridge'[ KEY InternetSales]='InternetSales'[ KEY InternetSales]
WHERE
	'Customer'[Gender] = 'M';

T?o ra r?t thêm 9 cau query n?a cho t?ng màu s?c:
SELECT
 DCOUNT ( 'InternetSales'[SalesOrderNumber] )
FROM 'InternetSales'
WHERE
	'InternetSales'[ KEY InternetSales] IN ( 25905, 26903, 30895, 29897, 27901, 32891, 59796, 20915, 18919, 54806..[30382 total values, not all displayed] ) VAND
	'InternetSales'[ KEY InternetSales] IN ( 26903, 7941, 54806, 51812, 47820, 8898, 6902, 30854, 46781, 44785..[4997 total values, not all displayed]?
..        

Cách 4: s? d?ng SUMX

#SalesOrderNumber 4 =
SUMX
(
? ? CALCULATETABLE(
? ? ? ? SUMMARIZE(
? ? ? ? ? ? ? ? 'Bridge',
? ? ? ? ? ? InternetSales[SalesOrderNumber]
? ? ? ? )
? ? ? ? , NOT ISBLANK(InternetSales[SalesOrderNumber])
? ? )
? ? ,
? ? 1
)         

Truy v?n: gi?ng cách 2

xSQL: ~93ms T?o b?ng t?m group by giá tr? l?i r?i ??y FE ?? tính toán ti?p.

No alt text provided for this image

SET DC_KIND="AUTO"
SELECT
'Product'[Color], 'InternetSales'[SalesOrderNumber]
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
	LEFT OUTER JOIN 'InternetSales' ON 'Bridge'[ KEY InternetSales]='InternetSales'[ KEY InternetSales]
WHERE
	'Customer'[Gender] = 'M' VAND
	'InternetSales'[SalesOrderNumber] NIN ( null ) ;        

Cách 4: s? d?ng TREATAS

#SalesOrderNumber 5 =
CALCULATE(
? ? DISTINCTCOUNT(
? ? ? ? 'InternetSales'[SalesOrderNumber]
? ? ),
? ? TREATAS(VALUES(Bridge[_KEY_InternetSales]),InternetSales[_KEY_InternetSales])
)         

Truy v?n: gi?ng cách 2

xSQL: ~4s, FE t?o ra quá nhi?u query.

No alt text provided for this image
ELECT
'Product'[Color], 'Bridge'[ KEY InternetSales]
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
WHERE
	'Customer'[Gender] = 'M';
--
SELECT DCOUNT ( 'InternetSales'[SalesOrderNumber] )
FROM 'InternetSales'
WHERE	'InternetSales'[ KEY InternetSales] IN ( 4520352, 1828075, 3556475, 2791952, 4620029, 5484229, 199352, 299029, 1063552, 3755829..[3038101 total values, not all displayed] ) VAND	'InternetSales'[ KEY InternetSales] IN ( 1828075, 3556475, 3755829, 3855506, 5882937, 1262906, 3955183, 3290337, 2326460, 2226783..[1466000 total values, not all displayed] ) ;        

3) ??m s? l??ng b?n ghi COUNT - > COUNTX ( ho?c cái khác )

Cách 1: s? d?ng tr?c ti?p Bridge, dùng SUMX

#Sale Rows 1 =
CALCULATE(
? ? SUMX( 'Bridge', 1)
? ? , Bridge[Stage] = "InternetSales"
)         

Truy v?n:

// DAX Quer
DEFINE
??VAR __DS0FilterTable =?
????TREATAS({"M"}, 'Customer'[Gender])
??VAR __DS0Core =?
????SUMMARIZECOLUMNS('Product'[Color], __DS0FilterTable, "v_Sale_Rows_1", 'InternetSales'[#Sale Rows 1])
EVALUATE
__DS0Corey        

xSQL:

No alt text provided for this image
WITH
	$Expr0 := 1
SELECT
'Product'[Color],
SUM ( @$Expr0 )
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
WHERE
	'Customer'[Gender] = 'M' VAND
	'Bridge'[Stage] = 'InternetSales';        

Cách 2: s? d?ng COUNTX th?ng qua bridge

#Sale Rows 2 = 
CALCULATE(
? ? countx( 
? ? ? ? 'Bridge', 
? ? ? ? RELATED(InternetSales[_KEY_InternetSales])
? ? )
? ? ,Bridge[Stage] = "InternetSales"
)         

Truy v?n: t??ng t? 1

xSQL:

No alt text provided for this image
SELECT
'Product'[Color],
COUNT (? )
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
	LEFT OUTER JOIN 'InternetSales' ON 'Bridge'[ KEY InternetSales]='InternetSales'[ KEY InternetSales]
WHERE
	'Customer'[Gender] = 'M' VAND
	'Bridge'[Stage] = 'InternetSales' VAND
	'InternetSales'[ KEY InternetSales] IS NOT NULL;        

Cách 3: s? d?ng CROSSFILTER

#Sale Rows 3 =
CALCULATE(
? ? count( 
? ? ? ?InternetSales[_KEY_InternetSales]
? ? )
? ? ,CROSSFILTER(Bridge[_KEY_InternetSales], InternetSales[_KEY_InternetSales],Both)         

Truy v?n: t??ng t? 1

xSQL:

No alt text provided for this image

4 Query, 3 query, 1 còn l?i g?p e query l?i

#1
DEFINE TABLE '$TTable3' := SELECT
'Product'[Color], 'InternetSales'[ KEY InternetSales]
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
	LEFT OUTER JOIN 'InternetSales' ON 'Bridge'[ KEY InternetSales]='InternetSales'[ KEY InternetSales]
WHERE
	'Customer'[Gender] = 'M';

#2
DEFINE TABLE '$TTable4' := SELECT
SIMPLEINDEXN ( '$TTable3'[InternetSales$ KEY InternetSales] )
FROM '$TTable3';

#3
DEFINE TABLE '$TTable1' := SELECT
'$TTable3'[Product$Color],
SUM ( '$TTable2'[$Measure0] )
FROM '$TTable2'
	INNER JOIN '$TTable3' ON '$TTable2'[InternetSales$ KEY InternetSales]='$TTable3'[InternetSales$ KEY InternetSales]
REDUCED BY
'$TTable2' := SELECT
'InternetSales'[ KEY InternetSales],
SUM (? ( PFDATAID ( 'InternetSales'[ KEY InternetSales] ) <> 2 )? )
FROM 'InternetSales'
WHERE
	'InternetSales'[ KEY InternetSales] ININDEX '$TTable4'[$SemijoinProjection];        

Cách 4: dùng TREATAS

#Sale Rows 4 =
CALCULATE(
? ? count( 
? ? ? ?InternetSales[_KEY_InternetSales]
? ? )
? ? ,TREATAS(VALUES(Bridge[_KEY_InternetSales]), InternetSales[_KEY_InternetSales])
)          

Truy v?n: t??ng t? 1

xSQL:

No alt text provided for this image
1
DEFINE TABLE '$TTable3' := SELECT
'Product'[Color], 'Bridge'[ KEY InternetSales]
FROM 'Bridge'
	LEFT OUTER JOIN 'Product' ON 'Bridge'[ KEY Product]='Product'[ KEY Product]
	LEFT OUTER JOIN 'Customer' ON 'Bridge'[ KEY Customer]='Customer'[ KEY Customer]
WHERE
	'Customer'[Gender] = 'M';
#2
DEFINE TABLE '$TTable4' := SELECT
'$TTable3'[Bridge$ KEY InternetSales]
FROM '$TTable3';
#3
DEFINE TABLE '$TTable5' := SELECT
RJOIN ( '$TTable4'[Bridge$ KEY InternetSales] )
FROM '$TTable4'
	REVERSE BITMAP JOIN 'InternetSales' ON '$TTable4'[Bridge$ KEY InternetSales]='InternetSales'[ KEY InternetSales];
#4

DEFINE TABLE '$TTable1' := SELECT
'$TTable3'[Product$Color],
SUM ( '$TTable2'[$Measure0] )
FROM '$TTable2'
	INNER JOIN '$TTable3' ON '$TTable2'[InternetSales$ KEY InternetSales]='$TTable3'[Bridge$ KEY InternetSales]
REDUCED BY
'$TTable2' := SELECT
'InternetSales'[ KEY InternetSales],
SUM (? ( PFDATAID ( 'InternetSales'[ KEY InternetSales] ) <> 2 )? )
FROM 'InternetSales'
WHERE
	'InternetSales'[ KEY InternetSales] ININDEX '$TTable5'[$SemijoinProjection];        

K?t lu?n

?a ph?n các tình hu?ng s? d?ng các hàm X ?em l?i hi?u n?ng t?t nh?t. Nh?ng 1 s? tr??ng h?p kh?ng th? d?ng thì chúng ta v?n lu?n có cách ?? hoàn thành c?ng vi?c. Queryplan cho MIN, MAX thì t??ng t? SUM nên t?i kh?ng có ??a ra s? li?u ? ?ay.

Link file demo Download

要查看或添加评论,请登录

Nghia Tran的更多文章

社区洞察

其他会员也浏览了