MDX IIF Statement aggregation - mdx

I have a very simple IIF statement in my cube calculation to create a calculation called "Commissionable Units":
IIF([Measures].[Commission]>0, [Measures].[Unit Balance]*1, NULL)
At the lowest grain I get the correct result, but as soon as I aggregate at any level, I get incorrect results
Example:
transaction #, Unit Balance, Commission, Commissionable Units
1, 500, 3, 500
2, 100, 0, 0
3, 250, 1, 250
When I remove the transaction dimension I get:
850, 4, 850
I should get:
850, 4, 750
I should mention that commission and units are in two different fact tables as they are different grains.

Related

SQL: removing duplicates based on different criteria, actually creates new records

I have a data base (dbo) with duplicates. In particular, one employee can work two roles (Role Number) in the same business (Business code) or work two / the same role within different business in the same or different area (Area Code), see below:
What I want is to remove duplicate records. Thus, I created this code:
Select
dbo.year,
min(dbo.RoleNumber) AS Role,
min(dbo.AreaCode) AS Area,
min(dbo.BusinessCode) AS BCode,
dbo.EmployeeNumber
From dbo
Group by dbo.year, dbo.EmployeeNumber
This code works well when an individual works the lowest role in a business with the lowest number and in the lowest area (e.g., row n* 3 and 4 in my example) or where the area code and business code are the same in the duplicate records (e.g., row n* 1 and 2).
However, I have some cases where an individual’s lowest role is associated with a higher Business code or/and area code. In this case, SQL creates new records combining these elements see examples below:
rows 5-10: 2018, 651, 5110, 3, 17;
rows 11-13: 2018, 649, 6215, 4, 20;
rows 14-15: 2018, 750, 5101, 5, 24.
This is not a problem per se, but it is problematic when I join tables to get additional data for these employees. The key elements to join tables are Area and business codes and employee's number, however with my code SQL is creating new records that do not exist in other tables, this leads to additional data being NULL.
Is there a way to fix this? I need SQL to always select the lowest Role number first, if the role number is the same then the lowest establishment number should be selected and if the same, the lowest Area code should finally be selected.
So for instance, I would expect that the three records creating problems would be retrieved like this:
rows 5-10: 2018, 651, 6319, 3, 17;
rows 11-13: 2018, 650, 6215, 4, 20;
rows 14-15: 2018, 750, 8076, 5, 24.
Thank you
Silvia
you can use window function:
select * from
(
select * , row_number() over (partition by year, employeenumber order by rolenumber,businesscode,areacode) rn
from youratble
) t
where rn = 1
you can play with order by inside the window function to choose the row you want.

calculation not working in rollup totals

I'm trying to create a calculated member in SSAS that will give me this below:
I want to create a new measure "AdjustedQuantity" that is basically the Length * Quantity (normalized to 30). Both Length and Quantity are in the same fact table.
See image below. example: if length is 15, the quantity should be halved, since 15 is half of 30. if length is 60, quantity should be doubled, etc. The AdjustedQuantity field is what I want, but my results (shown in "MyAttempt_WRONG" column) don't give me the correct totals. Note I also have [Length] as a dimension.
Note: Length can be 30, 60, 15, 45, others.
CREATE MEMBER CURRENTCUBE.[Measures].[MyMeasure]
AS [Measures].[Quantity] * ([Measures].[Length]/30),
The solution which will perform best is to add a column to the DSV which is:
Quantity * Length/30
Then create a Sum measure on that column.
If you must do it in MDX despite worse performance that the above try:
CREATE MEMBER CURRENTCUBE.[Measures].[MyMeasure]
AS SUM(
EXISTING [Your Length Dimension].[Length].[Length].Members,
[Measures].[Quantity] * (Your Length Dimension].[Length].CurrentMember.Member_Key/30)
);
Basically you need to do the multiplication per Length the sum up from there. Member_Key assumes the Length dimension attribute key is the integer representation of the Length.

MDX grouped dimensions

I have a dimension [product].[type] having its member containing 'Food','Book','Metal','Meat', etc. My task is to show a categorized dimension to group my sales value, such as, group Food & Meat as 0, Metal & Tool as 1, Book as 2, etc..
My Query seems doesn't work:
WITH calculated member [Measures].[Grouped Type] AS
IIF([product].[type].CurrentMember IS [product].[type].[Meat], 0,
IIF([product].[type].CurrentMember IS [product].[type].[Food], 0,
IIF([product].[type].CurrentMember IS [product].[type].[Tool], 1,
...... , 9)))))
SELECT {[Measures].[Sales Amount], [Measures].[Grouped Type].Children} on 0
FROM Cube
WHERE ([Condition])
It looks my total sales amount is shown, but not correctly categorized. any help? Appreciated.
Try calculated members against the product dimension, not measure's one:
With
Member [product].[type].[0] as
Sum({[product].[type].[Meat],[product].[type].[Food]})
Member [product].[type].[1] as
Sum({[product].[type].[Tool]})
select
[Measures].[Sales Amount] on 0,
{[product].[type].[0],[product].[type].[1]} on 1
From Cube
Where ([Condition])

Calculate 'R Square' and 'P-Value' for multiple linear regression in TSQL

We just have few built-in functions in SQL Server to do sophisticated statistical analysis but I need to calculate multiple linear regression in TSQL.
Based on this post (Multiple Linear Regression function in SQL Server), I could be able to get Coefficients for Intercept (Y), X1 and X2.
What I need is p-value for X1 and X2 and also R Square
Test data:
DECLARE #TestData TABLE (i INT IDENTITY(1, 1), X1 FLOAT, X2 FLOAT, y FLOAT)
INSERT #TestData
SELECT 0, 17, 210872.3034 UNION ALL
SELECT 0, 23, 191988.2299 UNION ALL
SELECT 0, 18, 204564.9455 UNION ALL
SELECT 0, 4, 189528.9212 UNION ALL
SELECT 0, 0, 200203.6364 UNION ALL
SELECT 11, 0, 218814.1701 UNION ALL
SELECT 5, 0, 220109.2129 UNION ALL
SELECT 2, 0, 214377.8534 UNION ALL
SELECT 1, 0, 204926.9208 UNION ALL
SELECT 0, 0, 202499.4065 UNION ALL
SELECT 0, 3, 196917.8182 UNION ALL
SELECT 0, 9, 202286.0012
Desired output:
R Square 0.4991599183412360
p-value X1 0.0264247876580807
p-value X2 0.7817597643898020
I have already been able to get following data from the above test data.
b Coefficients
----------------------------------
Intercept (Y) 202119.231151577
X1 C(H) 1992.8421941724
X2 C(C) -83.8561622730127
I know TSQL is not a good platform to obtain this but I need it to be done purely in TSQL.
I am aware of XLeratorDB Function Packages for SQL Server
You could calculate R Squared by hand and create a variable 'R2' equal to
(Nxysum - xsumysum)^2/ (Nx2sum - xsumxsum) (Ny2sum - ysumysum)?
Where xsum and ysum are the sum of your values and N is the number of observations.
The formula for R Squared is simple enough that you don't necessarily need any function or statistical software. Check out this link for calculating it by hand: http://sciencefair.math.iit.edu/analysis/linereg/hand/
You can apply the same logic to T-SQL.

Count records by groups while drilling down in the recordset

I am working on a website which has a drill down feature for a large recordset.
Lets say I have the following recordset:
tblBrand (ID, Name, PriceFrom, PriceTo, BHPFrom, BHPTo)
1, Audi, 170000, 340000, 100, 250
2, BMW, 250000, 290000, 110, 400
3, Ford, 275000, 500000, 75, 150
4, Kia, 110000, 250000, 50, 100
5, VW, 135000, 460000, 50, 200
To the user I will by default show all records. And in my drill down feature, I am presenting to the user URLs like this:
Price:
0-100000 (0 brands)
100000-200000 (3 brands)
200000-300000 (5 brands)
300000-> (3 brands)
BHP:
0-100 (3 brands)
100-200 (5 brands)
200-> (3 brands)
So far so good. I got the solution to the count-by-ranges problem here: Group a range towards a range
But my problem occurs when the user clicks on one of my drill-down links. Lets say he clicks on "BHP 0-100". Then it will only be tblBrand ID 3,4,5 to be displayed. This is of-course easy with a simple WHERE clause. But here is my question:
How do I present to the user an updated count of Brands per Price-range and Brands per BHP-range after the user has done the first drill-down by selecting "BHP 0-100"?
Currently my solution (which works) is to insert the resulting recordset after the drill down into a temp-table and do all the new counting on that table. This is an easy way, but with 100k+ records and +/- 20 types of drill down possibilities each having 5-20 ranges, it becomes a very heavy task!
UPDATE: This is what I am doing (pseudecode):
SELECT INTO #DrillDownRecordset (ID, Name)
FROM tblBrand
WHERE BHPFrom > #SelBHPFrom AND BHPTo < #SelBHPTo
SELECT COUNT (ID)
FROM #DrillDownRecordset
GROUP BY PriceRanges
SELECT COUNT (ID)
FROM #DrillDownRecordset
GROUP BY BHPRanges
This works, but is very heavy..
Could I be looking at using ROLLUP?