AND/OR Statement in Tableau - tableau-api

Does anyone know how to transcribe this in Tableau:
WHERE DATE(created) = '2021-01-01'
AND (source = 'T' OR (a.promo = 'TK' AND source != 'T'))
Basically, I'm validating if source equals to "T" and grabbing all those results, but sometimes a promo but does not get flagged under the "T" source.
Is there a way to have filter that validates under this nested WHERE clause?
Thanks in advance!

If you're wanting to use a calculated field in the place of SQL then:
IF DATE([created]) = '2021-01-01'
AND ([source] = 'T' OR ([promo] = 'TK' AND [source] <> 'T'))
THEN [measure or dimension] END
That's assuming that the fields in Tableau end up being given those names.
EDIT
The calculated field above works by just ignoring data that doesn’t meet the conditions, which is very flexible — effectively pulling the condition from the WHERE clause into the SELECT clause of the query that Tableau generates.
In some other cases, you really do want to first filter to a set of data and then calculate on the resulting rows — either for performance or logic reasons.
In that case, you can define a boolean calculated field with just the condition, put it on the Filter shelf, and choose to filter to records whether the calculated field evaluates to True.
Both approaches are useful.

Related

Tableau KPI prev value depending on variable

am trying to get Previous Sum(of someField) based on a variable value which is an Id.
This is not a table, Im doing a KPI
On Qlik you would do something like:
SUM({<Id={"$(=Max(vVariable),-1))"}>} someField)
But I can not achieve it on Tableau, off course is due to my lack of knowledge, unfortunatelly time is tinking at work and wanted to see if anyone has any input!
Thanks
Assuming you may use a sample input like the Superstore (using sales as metric), this could be what you're looking for:
In red you can see your "variable" which allows you to select a value and in blue you'll find the unique row for the previous value (Order ID sorted).
The first thing you need to to do is creating a parameter based on all the Order ID values:
Then things start to get a bit complicated if you're not familiar with LOD (Level of details) and the order of execution in Tableau, especially for filters.
Assuming that you can get some information on your own (otherwise, feel free to ask), the first thing you nee to to do is to "pre-calculate" the equivalent of a table having a rowe for each Order ID, in which you also have the previous Order ID value.
You can achive this combining Fixed (LOD) and Lookup function, creating this Calculated Field "Lookup Order ID":
LOOKUP( max({ FIXED [Order ID] : MAX([Order ID])}),1)
This is actually just a calculated field that you want to "fix" because you need the filter to act after you have made that previous calculus, and then you shift your data by 1 row backward.
Once you've done that, you just nee to create another calculated field in order to test your parametric value, and it could be something like this "check param":
[Lookup Order ID] = [Order ID param]
Moving this calculated field in the filter section and selecting just "true" values, you'll get that unique rows like in the initial image, showing the previous value (blue) related to the one you select in the parameter drop-down menu (red).

Summing 2 Statements Tableau

In Tableau, what are the rules when it comes to adding 2 statements if you cannot put everything in 1? In the first part of the statement below, I am trying to pull all products besides 1 of them from a distributor, then in the part I am trying to pull all the units except from 2 of the distributors. However, as you can guess, the cells are blank when I drag the pill over.
Is it best practice to just create 2 calculated fields and add THOSE together?
(IF [Distributor] = "NDC"
AND [Product] <> "PE Single Use"
THEN ['15] END)
+
(IF [Distributor] <> "NDC"
AND [Distributor] <> "M&D"
THEN ['15] END)
Here are a few simple rules about calculations in Tableau (and generally in SQL also)
If you don't specify a value in some case, say by leaving off the else clause in an if statement, the expression evaluates to null in that case. That can be fine or a problem depending on what you want. Consider null to mean no-value, or not-applicable or missing-value depending on your situation.
Nulls propagate through other expressions. A null value + anything yields a null value. You can explicitly test for null if necessary, but it is often better to keep simple expressions that evaluate to null when any part is null.
Aggregation functions like SUM(), MIN(), AVG() etc silently ignore null values. So AVG(Salary) is really the average of all the rows that had a non-null value in the Salary field. You don't get any warning about this, it is understood. If you want to know how many rows have a non-null value for a field, you can use the COUNT() function to check.
In your expression above, the two IF conditions are never both true for the same record. So at least one of the two halves of your expression is null in each case, so the resulting entire expression is always null.
There are other rules to learn when using table calcs and LOD calcs, but these rules apply throughout.

Make math operations on a grouped table

My problem is not in a real programming Language.
I have an exercise in ABAP Language but is not very important the language.
Anyway, I have a table:
I need to make the total cost of the position(after the select obviously).
Then, the table will be grouped by two fields (MATNR and BUKRS), so I need to know for each Group the total cost MAX, the total cost MIN and the total cost AVERAGE of the positions.
However I need a simple algorithm to solve this problem (pseudo-code).
I hope I was clear.
For table aggregations I find the AT functions within a LOOP very handy.
Sort your fields according the dimensions you need and sort the values within ascending or descending.
The order of the fields is very important here, because the AT looks for changes in the specified field and all fields left of it in the same row. So you handle group for group and append the result of the group aggregation to your result table.
LOOP AT lt_itab ASSIGNING <ls_itab>.
AT NEW bukrs. "at first entry of combination matnr, bukrs
ls_agg-matnr = <ls_itab>-matnr.
ls_agg-bukrs = <ls_itab>-bukrs.
ENDAT.
TRY.
ADD <ls_itab>-amount TO lf_sum.
CATCH cx_sy_arithmetic_overflow.
lf_sum = 9999.
ENDTRY.
lf_count = lf_count + 1.
IF <ls_itab>-amount > lf_max.
lf_max = <ls_itab>-amount.
ENDIF.
AT END OF bukrs. "after last entry of combination matnr,bukrs
ls_agg-avg = lf_sum / lf_count.
ls_agg-max = lf_max.
APPEND ls_agg TO lt_agged.
CLEAR: ls_agg, lf_sum, lf_count, lf_max.
ENDAT.
ENDLOOP.

Second Max in Tableau Calculated Field

How can I get the second highest value from a field in a calculated field. In excel I would use the large function but there doesn't seem to be a tableau equivalent. I would prefer to do the calculation in Tableau instead of using a pass through function.
Here are two alternatives.
First, if you want the calculation to happen on the data source side, You could write a LOD calculation to find the max of your field, name it myMax
{fixed [My_Dimension1], [My_Dimension2] : max(myField)}
Whether you use fixed, include or exclude scope for the LOD calc depends on how you want to scope your analysis.
Then write a row level that returns the field value if it is less than the LOD calc, and implicitly null otherwise, name myFieldExceptMax
if myField < myMax then myField end
The max of that row level calc would be your answer.
max(myFieldExceptMax)
Alternatively, if you want to operate on the client (tableau) side to find the penultimate aggregated query result, you can use on of the ranking table calc functions, and the filter to only show the second ranking result.

Parameter to find all records or exclude NULL

I have found several articles on how to accomplish the reverse of what I want to do with several methods (IS NULL, CASE, COALESCE), but I think at this point I am more confused than ever after reading all this and probably making solution harder than it needs to be. I am new to T-SQL and I am currently using VS 2005 to build a basic medical report.
I have the Date Range parameter working properly by using a convert command to ignore time stamp giving me all records for the day or date range. I am now wanting to filter SSRS reprot by perliminary report date to find records with preliminary report, or, all records in table.
The database has NULL if no preliminary report was created
The database has time stamp if preliminary report was created. (showing date and time it was created)
I need to find all records not NULL, or all records. (using a parameter)
I have a parameter "Display Prelim Reports only?" #PrelimOnly with a YES or NO answer.
If I use the following it will show all records correctly (all records not NULL showing only records with Prelim report/time stamp present)
LIS_Results.Prelim_Report_Date <> '#PrelimOnly' ----User selects YES it passes NULL
however, if user selects NO, how would I get it to display all records including NULL?
Thank you for any help
Thank you both for your help, it was ultimately a combination of both that got it going. Syntax is as follows.
WHERE (#PrelimOnly = 'NO') AND (CONVERT(VARCHAR(10), LIS_Results.Final_Report_Date, 101) BETWEEN #ReportStartDate AND #ReportEndDate) OR (LIS_Results.Prelim_Report_Date IS NOT NULL) AND (CONVERT(VARCHAR(10), LIS_Results.Final_Report_Date, 101) BETWEEN #ReportStartDate AND #ReportEndDate)
Use an if statement in tsql to say if parameter is yes select records from table where conditions are true.
If no select records from table where conditions are true and date field is not null.
Since #PrelimOnly can only be YES or NO, use:
SELECT
...
FROM
...
WHERE #PrelimOnly = 'NO' or LIS_Results.Prelim_Report_Date is not null
...
If the parameter is NO, the left hand condition of the OR is satisfied and all rows are returned, otherwise only those non-null rows will be returned, as required.
here exist small trick:
((LIS_Results.Prelim_Report_Date <> '#PrelimOnly') OR (1=#AllowNull))
if user selected NO - set AllowNull argument to 1, other way set it to 0
NOTE: AllowNull - it is custom additional argument, you should add the same way as #PrelimOnly
another possible approach:
((LIS_Results.Prelim_Report_Date <> '#PrelimOnly') OR ('NO'='#PrelimOnly'))
for you full query you should do like this:
WHERE
(CONVERT(VARCHAR(10), LIS_Results.Final_Report_Date, 101) BETWEEN ReportStartDate AND ReportEndDate) AND
(
LIS_Results.Prelim_Report_Date is not null
or
('#PrelimOnly' = 'NO') // if instead of NO VS sends empty string replace it here
)
It was a combination of Iiya and Ian that got me the solution however the syntax was not complete and is as follows.
WHERE (#PrelimOnly = 'NO') AND (CONVERT(VARCHAR(10), LIS_Results.Final_Report_Date, 101)
BETWEEN #ReportStartDate AND #ReportEndDate) OR (LIS_Results.Prelim_Report_Date IS NOT NULL)
AND (CONVERT(VARCHAR(10), LIS_Results.Final_Report_Date, 101) BETWEEN #ReportStartDate AND
#ReportEndDate)
It requeired the Date and Time paramater to be repeated so that both paramters would still work, and the #PrelimOnly = 'NO' had to be first.