Làm thế nào để tính toán / lưu trữ Top 10 trong một mô hình bảng?


23

Gần đây chúng tôi đã tạo một mô hình bảng SSAS để người dùng của chúng tôi có thể truy cập nó thông qua PowerView. Chúng tôi có một số đo trên một trong các bảng thực tế của mình để TotalActiveItemssử dụng công thức:

TotalActive:=COUNTAX(FILTER('Stats', ISBLANK([DeactDate]) = TRUE), 1)

Điều này hoạt động rất tốt khi cần thiết nhưng bây giờ chúng tôi có một yêu cầu để có được 10 phụ huynh hàng đầu cho mỗi tháng trong TotalActive.

Để tham khảo, đây là một phần của mô hình của chúng tôi:

create table factStats
(
    StatsID INT IDENTITY NOT NULL PRIMARY KEY,
    DevID INT NOT NULL,
    DeactDate DATETIME NULL,
    BillDateTimeID BIGINT NOT NULL,
    CustID INT NOT NULL,
    ParentID INT NOT NULL
);

create table dimCust
(
    CustID INT NOT NULL PRIMARY KEY,
    CustName varchar(150) NOT NULL
);

create table dimParent
(
    ParentID INT NOT NULL PRIMARY KEY,
    ParentName varchar(100) NOT NULL
);

create table dimDateTime
(
    DateTimeID BIGINT NOT NULL PRIMARY KEY
);

SQL Fiddle với các bảng và dữ liệu mẫu.

Các factStatsbảng có FKS đến DevID, CustID, BillDateTimeID, và ParentID. Yêu cầu mà chúng tôi có là tính toán hoặc lưu trữ Top 10 Parentscho từng cái BillDateTimeIDdựa trên TotalActive AND bao gồm mọi thứ không nằm trong Top 10 trong danh mục cuộn lên tương tự như sau:

+----------------+------------+------+
| BillDateTimeID |   Parent   | Rank |
+----------------+------------+------+
|       20140801 | Jim        |    1 |
|       20140801 | Bob        |    2 |
|       20140801 | All Others |    3 |
+----------------+------------+------+

Tôi có thể dễ dàng thực hiện điều này trong SQL bằng các hàm cửa sổ nhưng cố gắng tái tạo điều này cho SSAS là khó khăn. Trong SQL, chúng tôi sẽ nhận được kết quả bằng cách sử dụng:

;with Total as
(
  select 
    ParentID,
    BillDateTimeID,
    sum(case when DeactDate is null then 1 else 0 end) TotalActive
  from factStats
  group by ParentID, BillDateTimeID
),
PRank as
(
  select 
    ParentID,
    BillDateTimeID,
    TotalActive,
    row_number() over(partition by BillDateTimeID 
                      order by TotalActive desc) pr
  from total
)
select 
  parentid,
  BillDateTimeID,
  TotalActive,
  pr
from prank
where pr <= 2
union all
select 
  0,
  BillDateTimeID,
  sum(TotalActive) TotalActive,
  3
from prank
where pr > 2
group by BillDateTimeID
order by BillDateTimeID desc, pr;

Bản thử nghiệm SQL Fiddle .

Tôi đã thử nhiều cách khác nhau để có kết quả nhưng mỗi cách đều có một vấn đề. Những nỗ lực của tôi là dưới đây.

Ban đầu, tôi có thể lấy phần nào dữ liệu bằng truy vấn MDX nhưng sau đó không biết làm thế nào để kết hợp dữ liệu này vào mô hình bảng của chúng tôi. Truy vấn MDX để tham khảo là:

with 
set [Top10Parent] AS
(
    (TOPCOUNT({ORDER(({[Parent].[Parent Name].[Parent Name]}),
        ([Measures].[Total Count]), BDESC)}, 10))
)
MEMBER [Parent].[Parent Name].[Others] AS
(
    AGGREGATE(EXCEPT([Parent].[Parent Name].[Parent Name], [Top10Parent]))
)
select 
    [Measures].[Total Count] on columns,
    {[Top10Parent]}+ {[Parent].[Parent Name].[Others]} on Rows
from [OurModel]
where {[Date and Time].[Month and Year].[Month and Year].[Jul 2014]};

Tất nhiên, điều này cũng chỉ cho tôi kết quả trong một tháng chứ không phải mỗi tháng.

Khi tôi nhận ra rằng truy vấn MDX sẽ không hoạt động, tôi đã bắt đầu bằng cách thay đổi factStatsbảng của chúng tôi để bao gồm một cột mới để gắn cờ các mục trong Top 10 và trong giá trị cuộn lên.

alter table factStats
    add Top10ParentID INT NOT NULL
    constraint DF_factStats default (0);

Ràng buộc mặc định tham chiếu giá trị "Đã cuộn" của chúng tôi cho Top 10.

Nỗ lực số 1: Tôi đã tạo bảng Top 10 mới để lưu trữ ParentID, tên và Xếp hạng:

create table dimTop10Parent
(
    Top10ParentID INT NOT NULL PRIMARY KEY,
    ParentName varchar(100) NOT NULL,
    Parent_Rank INT NOT NULL
);

Bảng này sau đó sẽ được điền mỗi lần chúng tôi làm mới mô hình của mình với Top 10 Cha mẹ mới dựa trên các mục Tổng số hoạt động mà họ có. Các Parent_Ranksau đó cột được ẩn trong mô hình bảng của chúng tôi và sử dụng độc quyền để phân loại. Điều này hoạt động rất tốt, ngoại trừ chúng tôi không có khả năng trong lịch sử để có được Top 10 vì nó không dựa trên cơ sở hàng tháng.

Nỗ lực số 2: Tạo một bảng mới để lưu trữ Top 10 nhưng KHÓA CHÍNH sẽ bao gồm cả Top10ParentID và BillingDateTimeID.

create table dimTop10Parent
(
    Top10ParentID INT NOT NULL,
    ParentName varchar(100) NOT NULL,
    Parent_Rank INT NOT NULL,
    BillDateTimeID BIGINT NOT NULL
);

Vấn đề với điều này là chúng ta không thể tạo mối quan hệ giữa FK đơn thực tế với PK hai phần trong dimTop10Parent trong mô hình dạng bảng.

Nỗ lực số 3: Tạo bảng mới nhưng sử dụng danh tính làm PK.

create table dimTop10Parent
(
    Top10ID INT IDENTITY NOT NULL PRIMARY KEY,
    Top10ParentID INT NOT NULL,
    ParentName varchar(100) NOT NULL,
    Parent_Rank INT NOT NULL,
    BillDateTimeID BIGINT NOT NULL
);

Các factStatsbảng sẽ lưu trữ các Top10IDgiá trị đó sẽ là duy nhất cho mỗi hàng. Tôi nghĩ rằng điều này sẽ giải quyết vấn đề của tôi, nhưng, không phải vì chúng ta không còn có thể sắp xếp theo Parent_Rankmô hình, nó đã gây ra lỗi:

Không thể sắp xếp ParentName theo Parent_Rank vì ít nhất một giá trị trong ParentName có nhiều giá trị riêng biệt trong Parent_Rank. Ví dụ: bạn có thể sắp xếp [Thành phố] theo [Vùng] vì chỉ có một vùng cho mỗi thành phố, nhưng bạn không thể sắp xếp [Vùng] theo [Thành phố] vì có nhiều thành phố cho mỗi vùng.

Sử dụng dữ liệu mẫu, kết quả cuối cùng sẽ tương tự (phần này hiển thị Top 2 với cuộn thứ 3):

| PARENTNAME | BILLDATETIMEID | TOTALACTIVE | PR |
|------------|----------------|-------------|----|
|     FDN    |   201408010000 |          11 |  1 |
|     FDO    |   201408010000 |           3 |  2 |
| All Others |   201408010000 |           5 |  3 |
|     FDN    |   201407010000 |          12 |  1 |
|     EVOD   |   201407010000 |           2 |  2 |
| All Others |   201407010000 |           5 |  3 |

Tại thời điểm này, tôi không biết làm thế nào để có được kết quả cuối cùng này. Tôi có thể thay đổi các bảng khi cần để lấy nó, tôi có thể thay đổi mô hình bằng cách sử dụng công thức, số đo, v.v. Tôi đã đọc về xếp hạng bằng các công thức DAX 1 , 2 , 3 nhưng dường như tôi không thể quấn đầu chúng đủ để có thể có được kết quả chính xác.

Làm cách nào tôi có thể tính toán / lưu trữ Top 10 này trong bất kỳ tháng nào mà vẫn có thể ghép dữ liệu khi cần trong mô hình bảng của chúng tôi?

Câu trả lời:


1

Tôi đã có một kịch bản tương tự và sử dụng truy vấn DAX sau đây ...

Đầu tiên, để đơn giản hóa, tôi đã xác định một biện pháp sử dụng bên trong DAX để tôi không phải lặp lại công thức. Sau đó, tôi đã sử dụng hàm tạo để lặp trên công thức TOPN:

define measure TableInTabular[NameOfTheMeasure] = COUNTAX(FILTER('Stats', ISBLANK([DeactDate]) = TRUE), 1)
evaluate
 (
  addcolumns
   (  
    filter
     (  
      generate
        (  
         VALUES(DatesTableName[Month]),  
         TOPN (10, VALUES(TableInTabular[ParentID]),TableInTabular[NameOfTheMeasure],0)
        ),
        TableInTabular[NameOfTheMeasure]>0
      ),
      "ActiveCount (or how you want to call this Column)",
      TableInTabular[NameOfTheMeasure]  
    )  
 )  
order by DatesTableName[Month] asc, 
TableInTabular[NameOfTheMeasure] desc

Với những điều trên, bạn nên có 10 ParentID hàng đầu và Số đo theo từng tháng. chỉ cần thay thế "TableInTabular" bằng tên bảng dạng bảng của bạn nơi bạn có dữ liệu và "DatesTableName" bằng tên của bảng ngày.

Xin vui lòng cho tôi biết nếu tôi hiểu nhầm câu hỏi của bạn và hy vọng nó sẽ giúp ...


1
Cảm ơn câu trả lời, vẫn còn một số vấn đề với điều này. Đầu tiên, tôi có thể sử dụng cái này trong SSMS nhưng nó đang được triển khai vào mô hình dạng bảng của chúng tôi để người dùng của chúng tôi có thể truy cập nó qua PowerView - họ sẽ không viết bất kỳ truy vấn nào - điều này chỉ cần có sẵn. Thứ hai, trừ khi tôi làm điều gì đó sai, không có đánh giá hoặc đặt hàng nào được cho phép trong mô hình bảng thông qua Visual Studio - không có tùy chọn nào cho việc này như là một chức năng. Thứ ba, truy vấn này chỉ trả về Top 10, tôi cũng cần dữ liệu cuộn lên hoặc một số cách để có được nó. Tôi sẽ tiếp tục chơi xung quanh với điều này mặc dù.
Taryn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.