Tableau: Sum of Sessions and Split - data-visualization

I have the following question!
I have a dataset looking like this.
Apl_id refers to each application, Session for each session the user is in, Date/Time and ser_offered
is the service the user uses.
I need to get the total time that each application lasted which i suppose it's something like
the Max(Date/Time) - Min(Date/Time) for each session and then get the Sum of those.
I want to do that for each the applications that is Completed(from se_offered).
Which is the best way to achieve that?
Thank you in advance and sorry for long post!

you can use the following method.
Create two LOD calculated fields as -
date_of_creation
{FIXED [apl_id] : MAX(
IF [ser_offered] = "Created" then [Date/Time] END
)}
and date_of_completion
{FIXED [apl_id] : MAX(
IF [ser_offered] = "Completed" then [Date/Time] END
)}
and then make a third LOD
desired result
{FIXED [apl_id]: MAX(DATEDIFF('hour', [date_of_creation], [date_of_completion]))}
Note: MAX in all three is used for aggregation only, and as such you can take MIN in all three too.
Moreover, first two LOD fields are optional you can directly calculate third one using calculation for those two there. That should work. Do tell whether it worked.
Thanks

Related

Doubleor triple timestamp issue

I am using SQL assistant and my data brings in snapshots from a huge database in the form of timestamps. Occasionally the snapshots bring in multiples per hour. The data is correct, multiple snapshots do happen from time to time within an hour, not always but it does happen.
I am bringing this into Spotfire and viewing by an hour and when more than one snapshot happens in the hour, the data shows as doubled.
I only want to display one per hour preferably the last(max) timestamp for the hour. Example; for the 7 am hour the data has a snapshot for 7:10 am and one for 7:55 am.
These are correct but I only want to display the last(max) timestamp, 7:55 am in this case. I can't figure the issue out in Spotfire so I am leaning towards a fix in SQL. How can I display only 1 for each hour?
You'd do this similarly to how you'd probably do it in SQL -- using a ranking/rownumber function.
The basic way Rank in Spotfire works is Rank(Order columns, order direction, partitioned columns, tie method)
You need to partition by the combination of Date and Hour, and then sort descending by your timestamp column.
So the code to identify the rows that you want to isolate should be something along the lines of:
Rank([TimestampColumn], "desc", Date([TimestampColumn]), Hour([TimestampColumn]), "ties.method=first")
What you do with it from here is going to depend on how you plan to use the data - for example, you can Limit Data Using Expression and set the code above = 1 which will limit your table accordingly (helpful if you don't want your users to accidentally forget to filter), or you can create a calculated column which turns it into a flag of some form like here:
If(Rank([TimestampColumn], "desc", Date([TimestampColumn]), Hour([TimestampColumn]), "ties.method=first") = 1, "Latest", "Duplicate")
Which allows your users to filter by this property. This way, they have the option to look at the extra rows.
Ultimately, though, if you want to only ever see these rows, and have no use for the earlier records, I'd probably do it in SQL, if you have that ability. This reduces the number of rows you have to load into your analytic.

DAX sum different DateTime

I have a problem here, i would like to sum the work time from my employee based on the data (time2 - time 1) daily and here is my query:
Effective Minute Work Time = 24. * 60 * (LASTNONBLANK(time2,0) -FIRSTNONBLANK(time1,0))
It works daily, but if i drill up to weekly / monthly data it show the wrong sum as it shown below :
What i want is summary of minute between daily different times (time2-time1)
Thanks for your help :)
You have several approaches you can take: the hard way or the easier way :). The harder (at least for me :)) is to use DAX to do this. You would:
1) create a date table,
2) Use the DAX calculate function to evaluate your last non-blank and first non-blank values (you might need to use calculate table, but I'm not sure; DAX experts jump in). Then subtract one vs. the other.
This will give you correct values for a given day for a given person. You can enforce the latter condition by putting a 'has one value' guard on the person name so that your measure informs the report author if they're not using it right.
Doing the same for dates is a little trickier. In the example you show you are including the date in the row grouping. But if you change your mind and want instead to have 'total hours worked by person' or 'total hours worked by everyone' you're not done with modelling yet.
Your next step is to use calculate table in combination with calculate to create a measure that returns the total. You'll use calculate table so you evaluate each date and the hours worked on that date by person. Then you'll use calculate to summarize that all down to a single number. If you're not careful with your DAX (or report authoring) you might mix which person you're summarizing for so that your first/last non blank are not at the person level. It gets intense quickly.
Your easier solution, though it might be more limited in its application - depends really on your scenario - is to use the query to transform the data into a summary by day and person using the group by command. This will give you a row per person per day with their start and end times. Then you can quickly calculate the hours worked on that day. Then you can quite easily build visuals on top of the summary data. Of course you give up some of the flexibility of the having a proper data model. However if you have a date table, a person table, and your summary table and then setup your relationships correctly you can achieve answers to the most common questions.

MAQL - Select all records that enclose a list of dates

I'm a bit of a noob in MAQL so I would like to know if it is possible to do the following thing :
I got a list of reservations with a Start Date and a End Date
I would like to be able to compute a metric that would give me (for reservations that match some criteria) the number of reservations that include a given night.
In the end, I want my metric to exist for each date x:
MyMetric(x) = Number of reservations with Start > x and End < x
I tried to do the following request:
SELECT COUNT(Voucher) WHERE Date(Start)<THIS AND Date(End)>THIS
but I'm having trouble setting up a report saying "Well now I want THIS to take all the values in the calendar".
(Voucher is just an attribute from my "Reservation" dimension).
Anyone knows how I can proceed ? The user manual is very difficult to read for someone who does not have an extensive experience with MAQL.
I unfortunately don't believe that what you're trying to achieve is possible with the data model you have. The reason behind this is because each date is associated with a specific action, such as the date in which a trip begins and when it ends. In order for this to work exactly how you want, it would be necessary to add a date dimension in the project that has a record for each date between the Begin and End date (e.g. Event date=generic date to capture a range of different events or snapshot date).
Hope this helps!

Aggregation of an MDX calculated measure when multiple time periods are selected

In my SSAS cube, I've several measures defined in MDX which work fine except in one type of aggregation across time periods. Some don't aggregate (and aren't meant to) but one does aggregate but gives the wrong answers. I can see why, but not what to do to prevent it.
The total highlighted in the Excel screenshot below (damn, not allowed to include an image, reverting to old-fashion table) is the simplest case of what goes wrong. In that example, 23,621 is not the grand total of 5,713 and 6,837.
Active Commitments Acquisitions Net Lost Commitments Growth in Commitments
2009 88,526 13,185 5,713 7,472
2010 92,125 10,436 6,837 3,599
Total 23,621 23,621
Active Commitments works fine. It is calculated for a point in time and should not be aggregated across time periods.
Acquisitions works fine.
[Measures].[Growth in Commitments] = ([Measures].[Active Commitments],[Date Dimension].[Fiscal Year Hierarchy].currentMember) - ([Measures].[Active Commitments],[Date Dimension].[Fiscal Year Hierarchy].prevMember)
[Measures].[Net Lost Commitments] = ([Measures].[Acquisitions] - [Measures].[Growth in Commitments])
What's happening in the screenshot is that the total of Net Lost Commitments is calculated from the total of Acquisitions (23,621) minus the total of Growth in Commitments (which is null).
Aggregation of Net Lost Commitments makes sense and works for non-time dimensions. But I want it to show null when multiple time periods are selected rather than an erroneous value. Note that this is not the same as simply disabling all aggregation on the time dimension. The aggregation of Net Lost Commitment works fine up the time hierarchy -- the screenshot shows correct values for 2009 and 2010, and if you expand to quarters or months you still get correct values. It is only when multiple time periods are selected that the aggregation fails.
So my question is how to change the definition of Net Lost Commitments so that it does not aggregate when multiple time periods are selected, but continues to aggregate across all other dimensions? For instance, is there a way of writing in MDX:
CREATE MEMBER CURRENTCUBE.[Measures].[Net Lost Commitments]
AS (iif([Date Dimension].[Fiscal Year Hierarchy].**MultipleMembersSelected**
, null
, [Measures].[Acquisitions] - [Measures].[Growth in Commitments]))
ADVthanksANCE,
Matt.
A suggestion from another source has solved this for me. I can use --
iif(iserror([Date Dimension].[Fiscal Year Hierarchy].CurrentMember),
, null
, [Measures].[Acquisitions] - [Measures].[Growth in Commitments]))
CurrentMember will return an error when multiple members have been selected.
I didn't understand much of the first part of the question, sorry...but at the end I think you ask how to detect if multiple members from a particular dimension are in use in the MDX.
You can examine either of the two axes as a string, and use that to form a true/false test. Remember you can use VBA functions in Microsoft implementations of MDX.
I suggest InStr(1, SetToStr(StrToSet("Axis(1)")), "whatever") = 0 as a way to craft the first argument of your IIF.
This gets the set of members on axis number one, converts it to a string, and looks to see if a certain string is present (it returns the position of that string within the other). Zero means not found (so it returns true). You may need to use axis zero instead, or maybe check both.
To see if multiple members from the same dimension were used, the test string above would have to be more complicated. You want to know if whatever occurs once or twice. You could test if the first occurance of the string was at the same position as the last occurance (by searching backwards); though that could also mean the string wasn't found at all:
IIF(
InStr(1, bigstring, littlestring) = InStrRev(bigstring, littlestring),
'used once',
'used twice or not at all'
)
I came across this post while researching a solution for my own issue with grand totals of calculated measures over time when filters are involved. I think you could have fixed the calculations instead of suppressing them by using dynamic sets. This worked for me.

hiding unnecessary fields in Access Report

At my workplace there is a "Daily Feedback" database where details are entered of any errors made by Customer Service Officers (CSOs), such as who made the mistake, when, and what service it was for. this is so we can gather data which would show areas where CSO's are repeatedly making mistakes so we can feed this back to them and train them in those areas if need be.
i currently have a report where an CSOs name is entered along with a date range and it produces the report showing the number of errors made for each service for that date range.
the code used is -
=Sum(IIf([Service]="Housing",1,0))
=Sum(IIf([Service]="Environmental Health",1,0))
etc etc for each Service.
The problem i have is that not every CSO does EVERY service and so there are usually a few results showing as "0". and i cannot be sure if thats because they dont do the service or if they are just very good at that service.
Being absolutely useless at SQL (or any other possible way of fixing this) i cannot figure out how to HIDE the entries that produce the zero value.
any help here would be greatly appreciated!
Assuming you have a table with the fields CSO, Service, FeedbackComments you could modify the report record source to
SELECT [CSO], [Service], Count([FeedbackComments])
FROM [FeedbackTable]
GROUP BY [CSO], [Service];
Then services which have no records will not appear on the report.
I don't understand exactly what you want. But I want to mention you can use the COUNT() function along with SUM(). A count >0 will reveal if 0 means '0' instances or '0' errors.