เราเพิ่งสร้างโมเดลตาราง SSAS เพื่อให้ผู้ใช้ของเราสามารถเข้าถึงได้ผ่าน PowerView เรามีมาตรการหนึ่งในตารางข้อเท็จจริงของเราเพื่อรับTotalActiveItems
สูตร:
TotalActive:=COUNTAX(FILTER('Stats', ISBLANK([DeactDate]) = TRUE), 1)
นี้ทำงานได้ดีตามความจำเป็น แต่ตอนนี้เรามีคำขอที่จะได้รับ Top 10 TotalActive
ผู้ปกครองในแต่ละเดือนในส่วน
สำหรับการอ้างอิงนี่เป็นส่วนหนึ่งของแบบจำลองของเรา:
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
);
ซอ Fiddleพร้อมโต๊ะและข้อมูลตัวอย่าง
factStats
ตารางมี FKs ไปDevID
, CustID
, และBillDateTimeID
ParentID
คำขอที่เรามีคือการคำนวณหรือจัดเก็บTop 10 Parents
สำหรับแต่ละรายการBillDateTimeID
ตามTotalActive
และรวมทุกอย่างที่ไม่อยู่ใน 10 อันดับแรกในหมวดหมู่สะสมที่คล้ายกับรายการต่อไปนี้:
+----------------+------------+------+
| BillDateTimeID | Parent | Rank |
+----------------+------------+------+
| 20140801 | Jim | 1 |
| 20140801 | Bob | 2 |
| 20140801 | All Others | 3 |
+----------------+------------+------+
ฉันสามารถทำสิ่งนี้ได้อย่างง่ายดายใน SQL โดยใช้ฟังก์ชั่นการเรียงหน้าต่าง แต่การพยายามทำซ้ำสิ่งนี้สำหรับ SSAS นั้นเป็นเรื่องยาก ใน SQL เราจะได้ผลลัพธ์โดยใช้:
;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;
SQL ซอสาธิต
ฉันลองหลายวิธีเพื่อให้ได้ผลลัพธ์ แต่แต่ละวิธีมีปัญหา ความพยายามของฉันอยู่ด้านล่าง
ในขั้นต้นฉันสามารถรับข้อมูลได้บ้างโดยใช้แบบสอบถาม MDX แต่ก็ไม่มีเงื่อนงำที่จะรวมสิ่งนี้เข้ากับแบบจำลองตารางของเรา แบบสอบถาม MDX สำหรับการอ้างอิงคือ:
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]};
แน่นอนนี่ยังให้ผลลัพธ์เพียงเดือนเดียวไม่ใช่ทุกเดือน
เมื่อฉันรู้ว่าแบบสอบถาม MDX ไม่ทำงานฉันเริ่มต้นด้วยการเปลี่ยนfactStats
ตารางของเราเพื่อรวมคอลัมน์ใหม่เพื่อตั้งค่าสถานะรายการใน 10 อันดับแรกและในค่าสะสม
alter table factStats
add Top10ParentID INT NOT NULL
constraint DF_factStats default (0);
ข้อ จำกัด เริ่มต้นอ้างอิงค่า "Rolled Up" ของเราสำหรับ 10 อันดับแรก
ลอง # 1: ฉันสร้างตาราง 10 อันดับใหม่เพื่อเก็บ ParentID ชื่อและอันดับ:
create table dimTop10Parent
(
Top10ParentID INT NOT NULL PRIMARY KEY,
ParentName varchar(100) NOT NULL,
Parent_Rank INT NOT NULL
);
จากนั้นตารางนี้จะถูกเติมแต่ละครั้งที่เรารีเฟรชโมเดลของเรากับผู้ปกครอง 10 อันดับใหม่ตามรายการรวมที่ใช้งานอยู่ Parent_Rank
คอลัมน์ถูกซ่อนอยู่แล้วในรูปแบบตารางของเราและใช้เฉพาะสำหรับการจัดเรียง วิธีนี้ใช้งานได้ดียกเว้นว่าเราไม่มีความสามารถในการรับ 10 อันดับแรกในอดีตเพราะมันไม่ได้ขึ้นอยู่กับเดือนต่อเดือน
ลอง # 2:สร้างตารางใหม่เพื่อเก็บ Top 10 แต่คีย์หลักจะมีทั้ง Top10ParentID และ BillingDateTimeID
create table dimTop10Parent
(
Top10ParentID INT NOT NULL,
ParentName varchar(100) NOT NULL,
Parent_Rank INT NOT NULL,
BillDateTimeID BIGINT NOT NULL
);
ปัญหาเกี่ยวกับสิ่งนี้คือเราไม่สามารถสร้างความสัมพันธ์ระหว่าง factStats FK เดี่ยวกับ PK สองส่วนใน dimTop10Parent ในโมเดลตาราง
ลอง # 3:สร้างตารางใหม่ แต่ใช้ข้อมูลประจำตัวเป็น 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
);
factStats
ตารางจะเก็บTop10ID
ค่าซึ่งจะไม่ซ้ำกันในแต่ละแถว ฉันคิดว่าสิ่งนี้จะแก้ปัญหาของฉันได้ แต่ไม่ใช่เพราะเราไม่สามารถเรียงลำดับตามParent_Rank
ในโมเดลได้อีกต่อไปมันส่งข้อผิดพลาด:
ไม่สามารถเรียงลำดับ ParentName โดย Parent_Rank เพราะอย่างน้อยหนึ่งค่าใน ParentName มีหลายค่าที่แตกต่างใน Parent_Rank ตัวอย่างเช่นคุณสามารถจัดเรียง [เมือง] ตาม [ภูมิภาค] เนื่องจากมีเพียงภูมิภาคเดียวสำหรับแต่ละเมือง แต่คุณไม่สามารถจัดเรียง [ภูมิภาค] ตาม [เมือง] เนื่องจากมีหลายเมืองในแต่ละภูมิภาค
การใช้ข้อมูลตัวอย่างผลลัพธ์สุดท้ายควรคล้ายกับ (ซึ่งแสดงให้เห็น 2 อันดับแรกที่มีการสะสมครั้งที่ 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 |
เมื่อมาถึงจุดนี้ฉันกำลังสูญเสียเกี่ยวกับวิธีการรับผลสุดท้ายนี้ ฉันสามารถเปลี่ยนตารางได้ตามต้องการฉันสามารถเปลี่ยนแบบจำลองโดยใช้สูตรการวัดและอื่น ๆ ฉันได้อ่านเกี่ยวกับการจัดอันดับโดยใช้สูตร DAX 1 , 2 , 3แต่ฉันไม่สามารถคาดศีรษะได้ พวกเขาเพียงพอที่จะสามารถรับผลลัพธ์ได้อย่างถูกต้อง
ฉันจะคำนวณ / เก็บ 10 อันดับแรกนี้สำหรับเดือนใด ๆ และยังสามารถแยกข้อมูลตามที่ต้องการในโมเดลตารางของเราได้อย่างไร