Please see below the following example:
Contract: Type of Contract: End Date:
Yamaha Active 01/01/2019
Suzuki Active 01/01/2014
Nissan Active 01/01/2018
Opel Disabled 01/01/2020
Mercedes Disabled 01/01/2013
Totals (distinct count) of the contracts that are marked as Active in the column Type of contract and have the column End Date showing a date greater than the current day. Hence, if the date today is 01/01/2017 the total distinct count should be 2 (Yamaha and Nissan).
Could you help in providing the correct MDX formula?
Thanks,
Shai
We don't see your cube structure to suggest something certain. There is no two or more contracts to see the different between regular one and distinct count from your example. Let's say you have Contract dimension with attributes (Contract,Type of Contract, End Date).
Set the value to your Contract attribute in YYYYMMDD format.
Add a calculated measure with the following MDX:
SUM(
existing [Contract].[Type of Contract].&[Active] * [Contract].[End Date].[End Date].Members,
IIF(
[Contract].[End Date].CurrentMember.MemberValue > Format(Now(),'yyyyMMdd'),
1,
NULL
)
)
If you need a distinct count of contractor name you may apply the same logic.
Related
I have a table books where users donate number of books:
username books date
____________________________________
Jon 3 2017-06-12
Jon 2 2017-05-20
Mary 4 2017-05-12
I want something like
username This month Previous Month
_______________________________________________
Jon 3 2
You will need some kind of grouping or conditional sum operations. The simplest way to get the result in your question - though which may not actually scale to your needs - is:
select username
,sum(case when dateadd(datediff(month,0,[date]),0) = dateadd(datediff(month,0,getdate()),0) then books else 0 end as ThisMonth
,sum(case when dateadd(datediff(month,0,[date]),0) = dateadd(datediff(month,0,getdate())-1,0) then books else 0 end as PreviousMonth
from books
where username = 'Jon'
group by username
Obviously with more details in your question you could get a better suited answer and one that is not specific to SQL Server should you be on a different DBMS. That said, the conditional and date logic is the same in all other DBMS implementations, you may just need to change the function names.
This works by adding the number of months between an arbitrary start date (the 0s in the functions above) and a date value to get the date at the start of the month. The dates returned by this logic for both your date value and today (the getdate() function) will return the same start of the month where they are both within the same calendar month. By adding one less month (the -1 in the script above) you get the start of last month, which you can then also compare to your date value to get the number of books for last month.
The sum and group by is there to 'flatten' your data into the one row per username value.
Have a funky issue i'm trying to resolve if you'd be so kind.
Measures: BillableHours
Dimensions:
Personnel (EmployeeId, EmployeeName)
Grouping(EmployeePeriodKey, ActiveFlag)
PeriodCalendarYear, CalendarQuarter, CalendarPeriod)
Grouping dimension has flags and calcs that are particular to a person in a period so the PK is the combo of EmployeeId and CalendarPeriod.
Data As Follows:
EmployeeId CalendarPeriod ActiveFlag BillableHours
123 201501 Y 10
123 201502 Y 20
123 201503 N 30
123 201504 Y 40
People are filtering on "Active Flag" = "Y" and missing the "N" row in the results which is not what is desired. Whatever filter I design needs to be flexible enough that at an employee level I need to know if an employee ever had a value of "Y" JUST the periods selected by the query.
Scenario 1: user selects employee 123 for periods 201501:201504 and filters hypothetical flag to "Y" - Billable Hours should be 100, not 70.
Scenario 2: user selects employee 123 for periods 201501:201503 and filters hypothetical flag to "Y" - Billable Hours should be 60, not 30.
Scenario 3: user selects employee 123 for period 201503 and filters hypothetical flag to "Y" - Billable Hours should be 0, not 30. since in this selected group of periods this person was not active for any period
i'm not interested in all siblings, just the ones at a person level. And if person is not selected I need it to know to perform this check on a person level for the periods filtered for. If they have the following
ActiveFlag: "Y"
Fiscal Year: 2016
Group BillableHours
IT Consulting 1000
HR Consulting 1500
It would be understood that those total amounts represent the hours for every employee who was active for any part of FY2016 whether all 12 months or only 1. If someone was active the year before, but weren't in 2016 they should not show up because I only want to interrogate the flags for the periods selected.
Do you want to see Y value when it's non empty? Otherwise N + Y value?
IIF(
[Measures].[BillableHours] > 0,
([Grouping].[ActiveFlag].[All],[Measures].[BillableHours]),
[Measures].[BillableHours]
)
WhatI needed to accomplish with the above is to have all values for a specific employee evaluated to see if any values for that employee were valid. The key to doing that ended up being using EXISTING. Additionally using NON_EMPTY_BEHAVIOR cut down on evaluation cycles because there was no need to evaluate the rows if they weren't active in a time period. I've posted the MDX below.
CREATE HIDDEN UtilizedFTESummator;
[Measures].[UtilizedFTESummator] = Iif([Measures].[Is Active For Utilization Value] > 0,[Measures].[Period FTE],NULL);
NON_EMPTY_BEHAVIOR([Measures].[UtilizedFTESummator]) = [Measures].[Is Active For Utilization Value];
//only include this measure if the underlying employee has values in their underlying data for active in utilization
CREATE MEMBER CURRENTCUBE.[Measures].[FTE Active Utilization]
AS
SUM
(
EXISTING [Historical Personnel].[Employee Id].[Employee Id],
[Measures].[UtilizedFTESummator]
),VISIBLE=0;
I want to calculate sales for promotion using it's date. I need 3 measures, avg sales from 21 days before promotion start date, sales in between of promotion's start and end date, and sales from 21 days after promotion's end date.
Why Visual Studio highlights avg in code below?
CREATE MEMBER CURRENTCUBE.[Measures].[Sales in promotion]
AS Avg(Existing([Promotion].[Promotion name].[Promotion name]),[Measures].[Sales]), ...
Same in here:
CREATE MEMBER CURRENTCUBE.[Measures].[Sales before promotion]
AS (EXISTING([Promotion].[Promotion name].[Promotion name]), AVG(strtomember("[Date].[Date].&["+ [Promotion].[Date].currentmember.member_key+"]").lag(21) : strtomember("[Date].[Date].&["+ [Promotion].[Date From].currentmember.member_key+"]"),
[Measures].[Sales])) ...
If I do sum(existing()) in first measure, the sum is calculated correctly, but it doesn't allow me to get average.
EXISTING will only help if [Promotion] is part of your query in either the WHERE or SELECT clause. If it is not included in either of these clause then EXISTING will be finding 1 member - the All member.
You could try NonEmpty and maybe move the period logic into a custom set?
WITH
SET [PERIOD] AS
STRTOSET(
"[Date].[Date].&["+ [Promotion].[Date].currentmember.member_key+"].lag(21)
:
[Date].[Date].&["+ [Promotion].[Date From].currentmember.member_key+"]"
)
From the code you posted I cannot tell if you want a daily average or and average per promotion ? Say there were 2 promotions over the 21 days does this mean you want (Total/2/21) ?
I have a transaction history that follows the below format, and I need to sum up the unique amounts per transaction.
Sample Data:
Transaction ID Transaction Date Activity Date Amount
1001 10/30/2014 11/5/2014 $50.00
1001 10/30/2014 11/7/2014 $50.00
1002 11/2/2014 11/14/2014 $100.00
1002 11/2/2014 11/17/2014 $100.00
I tried two approaches, based on the way the data is formatted, either trying to filter for unique transaction ids:
=CALUCLATE(SUM(TRANSACTION HISTORY[AMOUNT]),DISTINCT(TRANSACTION HISTORY[TRANSACTION ID]))
Or to sum up based on the earliest activity date:
=CALUCLATE(SUM(TRANSACTION HISTORY[AMOUNT]),EARLIEST(TRANSACTION HISTORY[ACTIVITY DATE]))
Both formulas result in errors though. Anyone have an a different approach for how this could be summed? The answer I'm trying to get is Sum of Unique Amount = $150.
Thanks.
The way to approach this is probably with one of the X functions which iterate over the data specified performing the calculation under that context and then summarising the results. Try this:
=SUMX(
VALUES(transaction_history[Transaction_ID]),
AVERAGE(transaction_history[Amount])
)
My goal is to build a fact table which would be used to derive measures in SSAS. The measure I am building is 'average length of employment'. The measure will be deployed in a dashboard and the users will have the ability to select a calendar period and drill-down into month, week and days.
This is what the transactional data looks like :
DeptID EmployeeID StartDate EndDate
--------------------------------------------
001 123 20100101 20120101
001 124 20100505 20130101
What fields should my Fact Table have? on what fields should I be doing the aggregation? How about averaging it? Any kind of help is appreciated.
Whenever you design a fact table, the first set questions to ask yourself is:
What is the business process you're analysing?
What are relevant facts?
What are the dimensions you'd like to analyse the facts by?
What does the lowest (least aggregated) level of detail in the fact table represent, i.e. what is the grain of the fact table?
The process seems to be Human Resources (HR).
You already know the fact, length of employment, which you can calculate easily: EndDate - StartDate. The obvious dimensions are Department, Employee, Date (two role-playing dimensions for Start and End).
In this case, since you're looking for 'average length of employment' as a measure, it seems that the grain should be individual Employees by Department (your transactional data may have the same EmployeeID listed under a different DeptID when an employee has transferred).
Your star schema will then look something like this:
Fact_HR
DeptKey EmployeeKey StartDateKey EndDateKey EmploymentLengthInDays
-------------------------------------------------------------------------
10001 000321 20100101 20120101 730
10001 000421 20100505 20130101 972
Dim_Department
DeptKey DeptID Name ... (other suitable columns)
------------------------- ...
10001 001 Sales ...
Dim_Employee
EmployeeKey EmployeeID FirstName LastName ... (other suitable columns)
---------------------------------------------- ...
000321 123 Alison Smith ...
000421 124 Anakin Skywalker ...
Dim_Date
DateKey DateValue Year Quarter Month Day ... (other suitable columns)
00000000 N/A 0 0 0 0 ...
20100101 2010-01-01 2010 1 1 1 ...
20100102 2010-01-02 2010 1 1 2 ...
... ... ... ... ... ...
(so on for every date you want to represent)
Every column that ends in Key is a surrogate key. The fact you're interested in is EmploymentLengthInDays, you can derive a measure Avg. Employment Length and you would aggregate using the average across all dimensions.
Now you can ask questions like:
Average employment length by department.
Average employment length for employees starting in 2011, or ending in September 2010.
Average employment length for a given employee (across each department he/she worked for).
BONUS: You can also add another measure to your cube that uses the same column, but instead has a SUM aggregator, this may be called Total Employment Length. Across a given employee this will tell you how long the employee worked for the company, but across a department, it will tell you the total man-days that were available to that department. Just an example of how a single fact can become multiple measures.