Manipulating data lineage
- AutoReport
- Jul 12, 2023
- 3 min read
(Nguồn: Sqlbi.com)
Phần 1 chúng ta đã được giới thiệu hàm TREATAS như một hàm có thể hỗ trợ cho việc thay đổi data lineage của table dữ liệu. Tiếp theo chúng ta đề cập đề một số tình huống nâng cao hơn nhé.
Đề bài đưa ra chúng ta cần tính toánh doanh số bán hàng của mỗi sản phẩm của ngày đầu tiên. Giải pháp đơn giản là tìm ngày đầu tiên bán hàng sau đó tính doanh số với điều kiện ngày bán hàng bằng ngày đầu tiên đó :
FirstDaySales v1 :=
SUMX (
'Product',
VAR FirstSale =
CALCULATE (
MIN ( Sales[Order Date] )
)
RETURN
CALCULATE (
[Sales Amount],
'Date'[Date] = FirstSale
)
)
Kết quả theo từng Brand sẽ cho kết quả như bên dưới:

Kết quả giống như mong đợi, SUMX interate table Product bằng cách kích hoạt một context transition tương ứng với từng sản phẩm và trong đó ngày bán hàng được lọc trực tiếp ở bảng Sales mà không có bất kỳ lan truyền nào từ bảng Date.
Một giải pháp khác có cùng kết quả nhưng tối ưu hơn là tạo một table chứa tên các sản phẩm cùng với ngày bán hàng đầu tiên của sản phẩm đó. Sau đó, dùng kết hợp này để lọc xuống bảng Sales :
FirstDaySales v2 :=
VAR ProductsWithSales =
SUMMARIZE (
Sales,
'Product'[Product Name]
)
VAR ProductsAndFirstDate =
ADDCOLUMNS (
ProductsWithSales,
"Date First Sale", CALCULATE (
MIN ( Sales[Order Date] )
)
)
VAR Result =
SUMX (
ProductsAndFirstDate,
VAR DateFirstSale = [Date First Sale]
RETURN CALCULATE (
[Sales Amount],
'Date'[Date] = DateFirstSale
)
)
RETURN Result
Giải pháp trên thực ra vẫn chưa phải tối ưu vì SUMX vẫn phải kích hoạt context transition cho từng sản phẩm. Một giải pháp tốt hơn (vẫn chưa cho ra kết quả đúng) để tối ưu là áp dụng đối số lọc phía sau CALCULATE, cụ thể là lọc ở bảng Product & Date để lan truyền xuống dưới bảng Sales (leverage relationship) :
FirstDaySales v3 (wrong) :=
VAR ProductsWithSales =
SUMMARIZE (
Sales,
'Product'[Product Name]
)
VAR ProductsAndFirstDate =
ADDCOLUMNS (
ProductsWithSales,
"Date First Sale", CALCULATE (
MIN ( Sales[Order Date] )
)
)
VAR Result =
CALCULATE (
[Sales Amount],
ProductsAndFirstDate
)
RETURN Result
Rất tiếc, hướng xử lý này khá tốt nhưng kết quả lại trả về không mong đợi. Vấn đề nằm ở chỗ, mặc dù kết quả của hàm ADDCOLUMNS trong table ProductsAndFirstDate chứa sản phẩm và ngày nhưng dưới góc độ của data lineage thì của tên sp bắt nguồn từ Product[Product Name], ngược lại ngày từ cột Date First Sale lại không có data lineage của Date (từ kết quả của hàm MIN). Nói cách khác, cột ngày ở First Sales có data lineage của riêng nó mà không liền quan các table khác trong data model. Cách xử lý là thay đổi data lineage của cột First Sales bằng cách gán nó vào cột Date[Date]. TREATAS sẽ giúp chúng ta điều này :
FirstDaySales v4 :=
VAR ProductsWithSales =
SUMMARIZE (
Sales,
'Product'[Product Name]
)
VAR ProductsAndFirstDate =
ADDCOLUMNS (
ProductsWithSales,
"First Sale", CALCULATE (
MIN ( Sales[Order Date] )
)
)
VAR ProductsAndFirstDateWithCorrectLineage =
TREATAS (
ProductsAndFirstDate,
'Product'[Product Name],
'Date'[Date]
)
VAR Result =
CALCULATE (
[Sales Amount],
ProductsAndFirstDateWithCorrectLineage
)
RETURN Result
TỔNG KẾT
Hiểu được data lineage là một kỹ năng quan trọng. Và được xem là kiến thức nâng cao cho mọi người muốn khác biệt so với các DAXer còn lại.
Comments