Getting two separate values from one column - analytics

As mentioned above, I am currently trying to get two separate values derived from one column.
I have a column named statusDate, and I want to know whether if the status have been more than a month. If it's over a month, it will be categorized as Overdue, whereas, less than a month will be categorized as Pending.
This is what I have tried, however, it only gave me a value, either Pending or Overdue. However, I want both for comparison reason.
IF (DATEDIFF('month', today(), statusDate) > 1)
THEN 'OVERDUE'
ELSEIF (DATEDIFF('month', today(), statusDate) < 1)
THEN 'PENDING'
END
Is there anything wrong with my calculated field? Please help, thank you!
I have tried creating two different calculated fields and put both in the row section. However, the result was as following
I want to create a pie chart to show the percentage of Overdue(Long term) vs Pending(Short term).

However, I want both for comparison reason.
With your current setup you could easily compare the two values if you drag the calculated field on rows to get the values in separate rows or on colours if you want two differently coloured line graphs.
If you want to colour your pie chart for each state, use the pie as you have it and drag your calculated field to "Colour". This should split the pie as expected.
You could create two separate calculated fields as U.Y. Fried described although this doesn't really give you any additional possibility that you wouldn't already have with your current calculation.
In the majority of use cases it's a lot easier to compare values if they are in different rows (as you have it, separated by "overdue" and "pending") then comparing values that are in different columns.

Here is one way how to do it, You could create two fields by creating two calculated fields. the first you should call "overdue" use the following expression;
IF (DATEDIFF('month', today(), statusDate) > 1)
THEN 'OVERDUE'
END
for the "pending" use;
IF (DATEDIFF('month', today(), statusDate) < 1)
THEN 'PENDING'
END
IF you'd like to sum them up, return a number, for overdue use;
IF (DATEDIFF('month', today(), statusDate) > 1)
THEN 1
ELSE 0
END
do the opposite for pending.
Also you should take in consideration when it equals to exactly a month, use => for greater or equals, and =< for less or equals, it depends on your business logic.
Hope that this helps you!

Related

Chart showing a comparison after checking a checkbox

I'm trying to figure out how to connect checkbox with chart.
What I need to do is the following:
I have a chart showing two lines (two sets of data, lets name them A and B).
After checking a checkbox "compare A with previous period" or "compare B with previous period" those data disappear and instead of them a suitable comparison is shown.
I know that it is possible to make checkbox dependent chart like here:
https://datastudio.google.com/reporting/23a0d8ac-96c0-42cc-a991-5a21bc7c9962/page/VvbsB?s=rw4uzVA5G9Y
but I don't know how to do it.
I tried looking for the solution on the Internet, but nothing found.
Thank you for your help in advance.
A step by step introduction how to blend data and add checkboxes to show/hide graphs. Also how to do a calculation across datafields in different datasets, which were blended.
Add to the dataset a checkbox with the name compare_a_with_previous_period the field 3days average on/off with
case when compare_a_with_previous_period then 3days average else null end
Depending on the checkbox data is shown in that field or not (null). For blending/joining the data over different dates, a timeshift has to be done. Therefore, create a field date_old with
datetime_add(Date,interval 30 day)
Create an parameter show_differences with range 0 to 1 and add a field show_differences with
case when show_differences = 0 then 0 else 1 end
This will later be used to switch on/off the graph for the difference calculation.
Blend the data with itself using date and date_old as join and range. And rename the 3 day average to 3 days_old
Add the chart and click on the "add metric"
and enter
case when show_differences > 0 then 3days average - 3days_old else null end
to do a calculation between the bend datasets. Under Style set the missing data to "Line Breaks".

Expression to get a percentage

I have a report which has a transaction type as a row group. There are two different types. I want to get the percentage of one type 2 compared to type 1.
I am not sure how to do this, I assume I need to use an expression which states the name of the transaction type and then make a calculation based on the other type.
So Instead of a total for July being 300, I would like the percentage of SOP+ compared to SOP-, so in this case 1.96%. For clarity, the figures in SOP+ are not treated as negative.
When you design a query to be used in a report, it is generally easier to work with different types of values being in separate columns. You can let the report do most of the grouping and aggregation for you. In that case, the expression would be something like this:
=Fields!SOP_PLUS.Value / Fields!SOP_MINUS.Value
Since they are both in rows in the same column, you have to use some logic to separate them out into columns and then do the operation.
You'll need to add two calculated fields to your dataset. Use an expression like this to get the values:
=IIf(Fields!TYPE_CODE.Value = "SOP+", Fields!SOP.Value, Nothing)
In other words, you will have new columns that have just the plus and minus values with blanks in the other rows. Now you can use a similar expression to earlier to compare them.
=Max(Fields!SOP_PLUS.Value) / Max(Fields!SOP_MINUS.Value)
Keep in mind that the Max function applies to the current group scope. When you add in multiple row and column groups to the mix this can get more complicated. If that becomes an issue, I would suggest looking at rewriting the query to provide these values in separate rows to make the report design easier.
WITH table1([sop-], [sop+]) AS (
SELECT 306, -6
UNION ALL
SELECT 606, -14)
SELECT(CAST([sop+] AS DECIMAL(5, 2)) / CAST([sop-] AS DECIMAL(5, 2))) * 100.0 FROM table1;
Returns :
-1.960784000
-2.310231000

Apply different formatting to different columns in a column group

I have some summary data, by year, that I am displaying in a tablix, in a pivot table fashion. The first column is the year, each row is a single year, and each column contains counts and dollar amounts from a query.
By default all of the value columns are formatted the same way. However, I need the first 4 columns formatted as a whole number (total counts) and the last 2 columns formatted as currency or 2 decimal places with commas. As shown here, my counts have .00 that I don't want shown.
Here is something that will get you going in the right direction:
=IIf(Fields!Type.Value = "Claims Filed" OR Fields!Type.Value = "Claims Approved", FormatNumber(Fields!Value.Value, 0), FormatCurrency(Fields!Value.Value, 2))
You will have to fill in for the other options, or switch these around to use the money values in the first part of the IIf since it is the shorter list. But, this should give you a good idea of how this can be done.
It is just a simple matter of conditional formatting, SSRS style.

SSRS Conditional Expression

In SSRS report, I want to perform conditional color formatting where highest rank should be Green and lowest rank should be Red within a Regional Manager group as shown below
Note: Couple of options, I was thinking of includes
I am using custom code function, for deriving Min and Max value, and somehow if I can include grouping filter on Regional Manger then it could work, but don't know if that's possible
In dataset, I create extra columns for each column and store Min\max value in it. But less keen towards this option, since I have 24 different ranks and which would mean, I will need 24 different columns along with current 40 attributes
Any help would be appreciated
I know you don't want to do this for each column, but despite your misgivings it is probably the best approach. Based on my previous answer to your earlier related question you can colour the min and max for each group as follows.
Create a table with fields store, atvrank, and btvrank
Right click the row header, and select Add Group -> Row Group - Parent Group, and choose Regional Manager. Set the Group name to RegionalManagerGroup
Then set the background colour for your cells to
=iif(Fields!atvRank.Value = min(Fields!atvRank.Value, "RegionalManagerGroup"),
"Green",
iif(Fields!atvRank.Value = max(Fields!atvRank.Value, "RegionalManagerGroup"),
"Red",
"White"
)
)
This now finds the maximum and minimum within the current group instead of the whole dataset. You will need to set this expression for each field individually, but this is probably less effort than returning new rows from the database to determine the maximum and minimum for each field.
This approach will give the following output
Please seriously consider this solution. If you have further questions, please just ask.

couchdb map / reduce multiple keys filtering by date

I have a view setup with a map reduce. Right now this code works great:
function(doc) {
if (doc.type == 'test'){
if(doc.trash != 1){
for (var id in doc.items) {
emit([id,doc.items[id].name], 1);
}
}
}
}
function(keys,prices){
return (keys, sum(prices));
}
I get a return and when using the group parameter, it condenses everything just fine.
My issue/question, I want to add a third key.... DATE, so I may only reduce records from certain dates. So for example:
function(doc) {
if (doc.type == 'test'){
if(doc.trash != 1){
for (var id in doc.items) {
emit([date,id,doc.items[id].name], 1);
}
}
}
}
My issue is that since date is at the beginning of the array, the reduce groups by date, id etc. I know I use group_level and say just take the first key from the array or the first 2 keys, but that doesn't help either because afaik, group_level goes from left to right in the array. I could put the date on the end of the emit array, but that doesn't help either because I need to have values at the beginning of my startkey and endkey to search on.
Here is an example of the output of data:
{"key":["2012-03-13","356752b8a5f6871f3","Apple"],"value":1},
{"key":["2012-03-20","123752b8a76986857","Pear"],"value":1},
{"key":["2012-04-12","3013531de05871194","Grapefruit"],"value":1},
{"key":["2012-04-12","356752b8a5f6871f3","Apple"],"value":1},
I want APPLE to be added up in one row, here it's adding up apples by date first. I was able to successfully just add up all the apples if I remove DATE as the first key in the array, but then I can't search by date range.
Any ideas on how to accomplish this?
If I correctly understand what you want to do, then you'd want to put the date as the first element of your array, and use group_level as well as start_key and end_key.
Eg. startkey=[1, "someid"] endkey=[1,"someid",{}] group_level=2
Will get you all items from date 1 (obviously choose your own format here), with id "someid" and any name. It seems funny that you emit id's before names, and without having more information about what you're actually trying to accomplish, it's hard to advise your general data model. If ID is a "type" id meaning that many items share the same ID then this makes sense. If ID is a unique per item ID, then it does not. In that case, you'd want to emit "name" before ID...
Edit 1
As per your comment, to do a range of dates you do this:
startkey=[1] endkey=[5,{}] group_level=2
You will get everything from date 1 to date 5 grouped by id ie. apples, oranges etc. I use this exact technique in a very large scale production application. I actually formatted the dates as an easily human readable integers of the format yyyymmdd, so 20140624 would sort to the top. If I want everything from the start of the month till now grouped by my group ids, I call
startkey=[20140601] endkey=[20140624,{}] group_level=2
It works perfectly and as far as I can tell that's what you're looking to do. I also have a third key layer "detail" which allows me to provide a deeper level of grouping for items that need it. I can then call
startkey=[20140601, "someid"] endkey=[20140624, "someid",{}] group_level=3
To drill to the detail level for a particular id, or just use the previous query with group_level=3 if I want the details for every id. I'm certain you can make this work - I've solved this exact problem in a production application using the techniques described.
Edit 2
If you want to group all apples regardless of date, then you'll need to let apples be the first element in the key. You can then get all apples over all time as a single row in the view result using group_level=1, and Apples over a date range using group_level=2. The difference here is that you'll only be able to do the group_level=2 query on a single item type at a time. If you want the best of both worlds, you unfortunately just need to make 2 views. That's just how key ordering works... If you need fast response times for both types of queries, all item types over a date range, and all of a particular item not grouped by date, I believe 2 views is the only way to achieve that.
Note
Another thing to note is about your reduce function. Wherever possible it is highly recommended that you use the built in reduce functions. They're implemented in erlang and are highly optimized compared to custom javascript reduce functions.
In your case, just replace your reduce function with this
_sum
Easy hey?
If you post more info about your application, data model etc. then I'd be happy to help out more with your database design.

Resources