syntax help for comparison logic - oracle

I am trying to find out the loss of portfolios from the current month to the prior month.
What I want to see is what missing, basically when we compare the two months together I want to display what is not matching between the two
I have put this expression.
If([portfolio_code Current ]=[portfolio_code_Prior])
Then(Count([portfolio_code Current ])
Else(0)
I am not sure my if syntax is incorrect I just wanted to give an example
any insights?
[enter image description here]

Assuming there is one portfolio per row the count of portfolios that were in last month and not this month is...
total(
If ( [portfolio_code Current ] <> [portfolio_code_Prior] && [portfolio_code_Prior] is not null)
Then ( 1 )
Else ( 0 )
)
or
total(
case
when [portfolio_code Current ] <> [portfolio_code_Prior] and
[portfolio_code_Prior] is not null
then 1
else 0
end
)
If you want to see how many were "lost" from this month to last month (how many were added form last month to this month) you would need to reverse the logic.
If you want to see how many more or less, that is much simpler:
count(distinct [portfolio_code_Prior]) -
count(distinct [portfolio_code Current ])

If you want 0 when they don't match otherwise the portfolio code, then your logic looks okay.
If you want to ONLY see the rows that do not match then add a detail filter for the custom data item, let's call it compare, like this:
[Compare] <> 0
as far as counting, you can just select the column and use count (or count distinct) depending on what you want.

Related

DAX - CONCATENATEX TO FILTER AN UNRELATED TABLE

I have an unrelated table ('Selected Values Slicer') that is then used as a slicer to select values. I need to use these selected values to filter another table ('Results Table').
Doesn't seem to be working as I'd expect it to. The output shows a 0 when more then 1 item is selected but works ok when 1 value is selected
VAR __SelectedValues =
CONCATENATEX(
ALLSELECTED('Selected Values Slicer'[Description]),
'Selected Values Slicer'[Description],
",")
RETURN
CALCULATE(
[TotalCount],
'Results Table'[Description] IN {__SelectedValues}
)
__SelectedValues RETURNS "Selected Value 1,Selected Value 2"
What I'm expecting is __SelectedValues to RETURN "Selected Value 1","Selected Value 2"
The following syntax will return "Selected Value 1","Selected Value 2" as you asks
CONCATENATEX(
ALLSELECTED('Selected Values Slicer'[Description])
,"""" & 'Selected Values Slicer'[Description] & """"
,","
)
Regarding filtering. I was trying to use the string as filter, but I didn't manage it the way you want. I can't say what is the reason for DAX not to do that, but asked Marco Russo about the case. So, I'll add the answer since a get it (upd. the answer added to the end of the answer).
To filter the table with a string of CONCATENAX() you can try the following sytax ( I checked it with a dummy data):
VAR __SelectedValues =
CONCATENATEX(
ALLSELECTED('Selected Values Slicer'[Description])
,'Selected Values Slicer'[Description]
,","
)
RETURN
CALCULATE(
[TotalCount]
,FILTER(
'Results Table'
,CONTAINSSTRING(
__SelectedValues
,'Results Table'[Description]
)
)
)
Regarding result you want to achieve. A below code, I believe, is enough. You have a slicer and you want to apply its values to the result. I have a feeling, you don't need to change a contex to the slicer and no context can influence it. If it's not like that, then the code should be altered, but the idea remains the same - get a column with a unique values and use it as a filter. I checked the syntax and it was functioning.
CALCULATE(
[TotalCount]
,'Results Table'[Description] IN VALUES('Selected Values Slicer'[Description])
)
P.S.
My first answer was not ok. I messed some info and gave an incorrect input. I'm sorry for that.
P.S.S. The answer from Marco Russo:
"IN looks for an exact match in a table (IN VALUE is a better choice for your need, and a better one is:
TREATAS ( VALUES ( slicer[column1] ), table[color] )
The result of CONCATENATEX is a string, so you should use CONTAINSSTRING - DAX Guide to do the search, but it would be slower and potentially inaccurate."
This is the answer from his colleague

Max Val function not working as I expected it to work

I write this query I dont know why its not working for me can anyone suggest for me which is right
SELECT MAX(NVL(CPV.SR_NO,0)+1) INTO :CPV.SR_NO FROM CPV
WHERE VOUCHER_ID=4;
I have to bring MAX value I put 0 but it never bring 1 for first record after one record it worked properly mean if table is empty then first entry not give 1 after one record saved than its showed 1 even nvl is shown to null to 0 then + 1 please correct me
thanks
If there are no rows with VOUCHER_ID = 4, then you are taking MAX over zero rows, and that is always NULL - it doesn't matter what expression you are taking the MAX over. The NVL you used will only have effect if there are rows with VOUCHER_ID = 4, but in those rows you may have NULL in the SR_NO column. It won't help if there are no rows to begin with.
You could write the code like this **:
SELECT MAX(SR_NO) INTO :CPV.SR_NO FROM CPV WHERE VOUCHER_ID=4;
:CPV.SR_NO := NVL(:CPV.SR_NO, 0) + 1;
That is - apply the NVL (and also add 1) outside the SELECT statement.
With that said - what is the business problem you are trying to solve in this manner? It looks very much like an extremely bad approach, no matter what the problem you are trying to solve is.
** Note - I haven't seen qualified bind variable names before, like :CPV.SR_NO, but since the query works for you, I assume it's OK. EDIT - I just tried, and at least in Oracle 12.2 such names are invalid for bind variables; so I'm not sure how it was possible for your code to work as posted.
ANOTHER EDIT
The whole thing can be simplified further. We just need to pull the NVL out of MAX (and also the adding of 1):
SELECT NVL( MAX(SR_NO), 0) + 1 INTO :CPV.SR_NO FROM CPV WHERE VOUCHER_ID=4;

DAX formula to subtract columns

I am trying to calculate month over month difference but it makes data negative.
I created a measure, but it makes source data negative.
CALCULATE (
COUNTA ( SOURCE_DATA[COLUMN] ),
FILTER ( SOURCE_DATA, SOURCE_DATA[YYYYMM] = "201906" )
)
- (
CALCULATE (
COUNTA ( SOURCE_DATA[COLUMN] ),
FILTER ( SOURCE_DATA, SOURCE_DATA[YYYYMM] = "201905" )
)
)
The outcome is correct, but it changes data in previous month to negative.
This is due to the filter context and the way you've written the measure.
Look at the visual table. For the field corresponding to Column = 201905 and row = GA you get -16 813. This is because the context of the visual table tells CALCULATE to COUNTA(SOURCE_DATA[Column]) only when MtM = GA and Columns = 201905. However, adding the FILTER you also tell CALCULATE to keep these criteria AND also make sure that SOURCE_DATA[Column] = 201906 in the first calculate and 201905 in the second one.
This results in CALCULATE looking for rows where Column is both 201905 and 201906 at the same time. Or in other words you generate a venn diagram with no overlapping fields. Therefore the first calculate evaluates to 0 and the second to 16 813, so that the measure is actually evaluating 0-16813 = -16 813.
Since you didn't post any description of your data model I can inly guess what it looks like. However, since you're filtering on the SOURCE_DATA table I guess you don't use a Calendar table. This you should do! Have a calendar with a 1:* (1-to-many) relationship with the SOURCE_DATA and do filtering on the calendar. In addition you can have dynamically calculated day/week/month/year offsets so that you can create measures which don't have to be updated when there's a new month.
I think this video can be helpful: sqlbi videolecture
Also, have a look at this article: sqlbi filter in calculate

Most efficient way to filter multiple dimensions

Trying to get the [Number] and [Sum of Time Spent] for all Changes that were open during period 201405.
The best definition of open I can think of is is:
- Changes that were logged before or during the [MonthPeriod], while closed during or after the [MonthPeriod]
SELECT
[Measures].[Sum of Time Spent] ON COLUMNS
,
[FactChange].[Number].[Number] ON ROWS
FROM
[Change Management]
WHERE
(FILTER(
[DimLoggedDate].[MonthPeriod].[MonthPeriod]
,[DimLoggedDate].[MonthPeriod].MEMBERVALUE <= 201405
)
,
FILTER(
[DimClosedDate].[MonthPeriod].[MonthPeriod]
,[DimClosedDate].[MonthPeriod].MEMBERVALUE >= 201405
))
The above query returns a list with all numbers, with a null value when the filters in the WHERE clause don't apply. I would like to remove the NULL items.
Because the query returns ALL Numbers, I wonder if this is the most efficient query to solve the issue. Applying NonEmpty() would remove the numbers, but since all changes are enumerated, isn't this putting more stress on the system than required?
You do it simply by adding "Non empty" in the on Rows clause:
...
non empty [FactChange].[Number].[Number] on Rows
...

How do I get the aggr of two aggrs in QlikView?

If I want to find the maximum value of a column from two states aggregated by a member's ID, should this work?
=Aggr(
MaxString(
Aggr(NODISTINCT MinString({[State1]}DATE_STRING),MBR_ID)
+
Aggr(NODISTINCT MinString({[State2]}DATE_STRING),MBR_ID)
) , MBR_ID)
So if I had this data:
MBR ID DATE_STRING
1 20120101
1 20120102
1 20120103
And State1 had 20120101 selected and State2 has 20120103 selected, my expression would return 20120103 for member 1.
Thanks!
Edit: In SQL, this would look like:
WITH MinInfo (DATE_STRING, MBR_ID)
AS (SELECT MIN(DATE_STRING), MBR_ID FROM Table WHERE TYPE IN ('State1', 'State2') GROUP BY MBR_ID, TYPE)
SELECT MAX(DATE_STRING) DATE_STRING, MBR_ID FROM MinInfo GROUP BY MBR_ID
It would be easier to accomplish your goal if you convert your that to an actual date field
Assuming that you are using a chart where MBR_ID is the Dimension, if you want the maximum date (latest date) you can do the following:
=nummax(Max({[State1]}DATE_STRING),Max({[State2]}DATE_STRING))
To convert to a date, you can use this function:
date#(DATE_STRING,'[text format of the date]')
(The date format looks like YYYYMMDD to me, but if its day then month, you would use YYYYDDMM)
I'd suggest you format it in the script, so that you wont have to worry about it every time you need to use that date.

Resources