Accessing the ATTR field troubleshooting in Tableau? - tableau-api

I am working on Tableau server but I believe the problem I am facing does not correspond to tableau server specifically.
I am using two data sources ds1 and ds2 which are joined using the dimension Id . ds1 has a field city and ds2 has a field district. There is only 1 city corresponding to each Id but there can be multiple district corresponding to an Id .
I have created a calculated field Points in ds2 which is described in the code segment.
I have researched from different sites and blogs (including tableau support). I came to a close possible reason behind this and I might be wrong . The ATTR function which works on row level and identify if a row is unique then it outputs the dimension otherwise it outputs '*' . I think when I joined those two tables the district dimension in ds2 might have the '*' instead of actual district values, so it might not be able to compare the conditions in if statements of Point .
//Point//
IF [city] == "Delhi"
AND [district] == "Dist1"
AND [district] == "Dist2"
THEN "100 Section"
ELSEIF [city] == "Mumbai"
AND [district] == "Dist11"
AND [district] == "Dist12"
THEN "200 Section"
ELSE "Other Section"
END
When I insert data which satisfy the conditions in calculated field, it is going in Other section of the Point .I want it to go in desired section.
For instance
Id = 19
city = Delhi
district = Dist1
district = Dist2
district = Dist3
It should go in 100 Section but it is going in Other Section . What modifications should I do or add to make the Point work properly ?

Related

How to parameterize a column for aggregation in Power BI desktop?

I have users who would like to be able to modify what columns a table aggregates by. My issue is that I seem unable to do this in Power BI. I basically want to be able to do the following in SQL:
SELECT
<OrgLevel1>,
<OrgLevel2>,
SUM([Revenue])
FROM [Data]
GROUP BY
<OrgLevel1>,
<OrgLevel2>
;
where the user can change <OrgLevel1> and/or <OrgLevel2> to be any of { "(All)", [Department], [Product] }.
The issue may be related to this post: https://community.powerbi.com/t5/Desktop/Calculated-Column-Table-Change-Dynamically-According-to-Slicer/m-p/655991#M314800
Here's a link to a workbook that illustrates this issue, TestParameterizeGroupby.pbix (hosted by Google Drive). I've also included field definitions below with screenshots. Thanks for any help.
TestParameterizeGroupby.pbix
Link: TestParameterizeGroupby.pbix (hosted by Google Drive)
Problem
[Org Level 1] and [Org Level 2] fields are not recalculating from the users' selection. Only the default values are shown.
Expected result in table
"Org Level 1", "Org Level 2", "Revenue"
"(All)", "(All)", 28
Note
The purpose is to have parameterizable organization level fields so that the report user can aggregate by all, department, product, or both in either order.
Table and column definitions
'Data' = DATATABLE(
"Department",
STRING,
"Product",
STRING,
"Revenue",
DOUBLE,
{
{"DeptA", "ProdX", 5.0},
{"DeptA", "ProdY", 6.0},
{"DeptB", "ProdX", 10.0},
{"DeptB", "ProdY", 7.0}
}
)
'Data'[Org Level 1] = SWITCH(
'Org Level 1 Parameter'[Org Level 1 Parameter Value],
0,
"(All)",
1,
[Department],
2,
[Product]
)
// Problem: [Org Level 1] and [Org Level 2] fields are not recalculating from the users' selection. Only the default values are shown.
'Org Level 1' = DATATABLE(
"Org Level 1",
STRING,
"Org Level 1 Parameter",
INTEGER,
{
{"(0) (All)", 0},
{"(1) Department", 1},
{"(2) Product", 2}
}
)
'Org Level 1 Parameter'[Org Level 1 Parameter] = GENERATESERIES(0, 2, 1)
'Org Level 1 Parameter'[Org Level 1 Parameter Value] = SELECTEDVALUE('Org Level 1 Parameter'[Org Level 1 Parameter], 1)
Table 'Org Level 1' has a 1-1 relationship with 'Org Level 1 Parameter' on column [Org Level 1 Parameter].
The user selects the value for 'Data'[Org Level 1] by selecting the value for 'Org Level 1'[Org Level 1].
Tables and columns for [Org Level 2] are defined in the same way as [Org Level 1].
Screenshots
Report view:
Data view:
Model view:
Cross-reference to post in Power BI forum:
Power BI Forum: How to parameterize a column for aggregation
One solution to this is to add two list values parameters and use their values in Power Query M code to modify the database query. Lets assume that you have a table Data with columns Department, Product and Revenue. For simplicity I will add one more column, named Dummy Column, with all rows having the same value (e.g. null). I will explain why later in this post. So the table looks like this:
Then in your report specify a query when adding this table to your model (lets assume we will import it, but in general you can do this in DirectQuery too):
Now if you look the M code you will see the above query there:
Source = Sql.Database(".", "StackOverflow", [Query=" select ....
Now define couple of parameters, that the end-user can use to select how the data should be aggregated. Lets name them Level 1 and Level 2:
The value of a parameter can be used in M by parameter name, and & is used to concatenate strings. So if there is a parameter Name with value Samuel, the expression "Hello, " & Name & "!" will be evaluated as Hello, Samuel!. The idea is to check the value of our parameters and modify the database query accordingly.
In the select part, we will replace the name of the field selected, or we will put '' (empty string) in case of <All> (I surrounded parameter values with brackets to be more easily to distinguish parameter values from database field names). So the expression should look like:
"select " & (if #"Level 1" = "<Department>" then "Department" else ..." (and so on)
Because there is a space in our parameter's name, we need to surround it with #" and ", so Level1 can be referenced simply as Level1 in the code, but Level 1 becomes #"Level 1".
The group by part is a bit trickier. We should add a comma between field names, add or not field name, or even omit the group by at all (in case both parameters are set to <All>). To simplify this, I added one dummy column, with all rows having the same value (e.g. null) and always group by this column. This way building the group by clause is way more simpler - in case the parameter value is not <All>, we should add , fieldname. So the code could look like this:
"group by DummyColumn" & (if #"Level 1" = "<Department>" then ", Department" else ..." (and so on)
So the final M code is this:
let
Source = Sql.Database(".", "StackOverflow", [Query="select#(lf) " & (if #"Level 1" = "<Department>" then "Department" else if #"Level 1" = "<Product>" then "Product" else "''") & " as [Org Level 1]#(lf) , " & (if #"Level 2" = "<Department>" then "Department" else if #"Level 2" = "<Product>" then "Product" else "''") & " as [Org Level 2]#(lf) , SUM(Revenue) as Revenue#(lf)from Data#(lf)group by DummyColumn" & (if #"Level 1" = "<Department>" then ", Department" else if #"Level 1" = "<Product>" then ", Product" else "") & (if #"Level 2" = "<Department>" then ", Department" else if #"Level 2" = "<Product>" then ", Product" else "")])
in
Source
Now the end-user can change parameter values, by clicking Edit Queries -> Edit Parameters:
And select how to group the data:
By default, Power BI Desktop will warn you first time, when particular query is executed:
If you want to turn this off, go to File -> Options and settings -> Options -> (GLOBAL) Security and make sure Require user approval for new native database queries is not selected:
When the end-user changes parameter values, the data will change too, e.g.:
Or:
And so on...
This trick works well in Power BI Desktop when every user has its own copy of the .pbix file. However, if you publish it, first changing parameter values is not very convenient (you must go to datasat's settings) and more important, changing parameter values affects all users, which are looking at this report. You can also use it to modify Table.Group statements generated by Power Query Editor, in case you want to aggregate the data in Power BI, but changing the database query is easier and more flexible.
If you want to enable this scenario for concurrent multi-users scenarios for published reports, you can use slicers and What-if parameters. Unfortunately, What-if parameters can be numeric (you can't define the list of values there), so you can use measures to "decode" the int value of the parameter and write some DAX code to perform different aggregations accordingly. It is more work, but if it is needed, it can be made too.

Filter portal for most recently created record by group

I have a portal on my "Clients" table. The related table contains the results of surveys that are updated over time. For each combination of client and category (a field in the related table), I only want the portal to display the most recently collected row.
Here is a link to a trivial example that illustrates the issue I'm trying to address. I have two tables in this example (Related on ClientID):
Clients
Table 1 Get Summary Method
The Table 1 Get Summary Method table looks like this:
Where:
MaxDate is a summary field = Maximum of Date
MaxDateGroup is a calculated field = GetSummary ( MaxDate ;
ClientIDCategory )
ShowInPortal = If ( Date = MaxDateGroup ; 1 ; 0 )
The table is sorted on ClientIDCategory
Issue 1 that I'm stumped on: .
ShowInPortal should equal 1 in row 3 (PKTable01 = 5), row 4 (PKTable01 = 6), and row 6 (PKTable01 = 4) in the table above. I'm not sure why FM is interpreting 1Red and 1Blue as the same category, or perhaps I'm just misunderstanding what the GetSummary function does.
The Clients table looks like this:
Where:
The portal records are sorted on ClientIDCategory
Issue 2 that I'm stumped on:
I only want rows with a ShowInPortal value equal to 1 should appear in the portal. I tried creating a portal filter with the following formula: Table 1 Get Summary Method::ShowInPortal = 1. However, using that filter removes all row from the portal.
Any help is greatly appreciated.
One solution is to use ExecuteSQL to grab the Max Date. This removes the need for Summary functions and sorts, and works as expected. Propose to return it as number to avoid any issues with date formats.
GetAsTimestamp (
ExecuteSQL (
"SELECT DISTINCT COALESCE(MaxDate,'')
FROM Survey
WHERE ClientIDCategory = ? "
; "" ; "";ClientIDCategory )
)
Also, you need to change the ShowInPortal field to an unstored calc field with:
If ( GetAsNumber(Date) = MaxDateGroupSQL ; 1 ; 0 )
Then filter the portal on this field.
I can send you the sample file if you want.

Tableau Column Difference - as a dimension

I am looking for difference of two columns in Tableau. I have the formula with me.
IF ATTR([Valuation Profile]) = "Base" THEN
LOOKUP(ZN(SUM([Value])), 1) > - ZN(LOOKUP(SUM([Value]),0)) END
But I get it as a separate column in the columns sections. How do I get that in the rows section? Basically how to get the difference as a dimension?
Please see attached images of what I want and what I have. Apparently, I cannot upload my excel sheet and tableau worksheet here. So I have upload just the screenshots.
What I have - vs - What I want
Tableau Workbook
First off, there is no way that you can generate additional rows for your data in Tableau!
In your case however you could use a workaround and do the following:
Create a calculated field for BASE and one for CSA. The formula should
be IF [Valuation Profile] = 'BASE' THEN [Value] END and IF
[Valuation Profile] = 'CSA' THEN [Value] END respectively
Afterwards you can drag Measure Names onto your rows shelf and
replace the SUM([Value]) with your two newly created calculated fields
that should give you all three measures in different rows in your table
Reference: https://community.tableau.com/message/627171#627171
Use LOD expression to calculate the individual values first.
Create calculated fields 'BASE', 'CSA' and 'CSA-BASE' as below.
BASE:
{FIXED [Book Name]: SUM( if [Valuation Profile] = 'BASE' then Value else 0 end ) }
CSA:
{FIXED [Book Name]: SUM( if [Valuation Profile] = 'CSA' then Value else 0 end ) }
CSA-BASE
[CSA]-[BASE]
Solution

Surpassing NULL Values

I am creating a crystal report in which i have to ![enter image description here][1] show address in this format for every school
ADD1
ADD2
ADD3
CITY
DIST
PINCODE
and i am fetching data from database, all the above column have some NULL values in it like for SCHOOL A - ADD1,ADD2,ADD3 have NULL values and for school B ADD2,ADD3 and CITY have NULL values and same like rest schools have some null values now when i am writing formula for first school
IF ISNULL({TEMP_PAY.ADD1})THEN
(
IF ISNULL({TEMP_PAY.ADD2}) THEN
(
IF ISNULL({TEMP_PAY.ADD3})THEN
(
IF ISNULL({TEMP_PAY.CITY})THEN
(
IF ISNULL({TEMP_PAY.DIST})THEN
{TEMP_PAY.PIN}
ELSE
{TEMP_PAY.DIST}
)
ELSE
{TEMP_PAY.CITY}
)
ELSE
{TEMP_PAY.ADD3}
)
ELSE
{TEMP_PAY.ADD2}
)
ELSE
{TEMP_PAY.ADD1}
then the first address of all the schools are showing correct but when i put same formula with other parameters then first Scool give duplicate CITY and rest scool are the same and some gets correct
i want that where there is NULL it should escape the field and give the next field which have some value for the all above fields help me for the same as soon as possible as i have searched lot for the same issue but did not get any help....
Regards
Sanjeev
To the extent I understood your problem.... try below solution.
Since you are looking to pick next value if present value is NULL then you can use function NEXT.
IF ISNULL({TEMP_PAY.ADD1})THEN
NEXT({TEMP_PAY.ADD1})
ELSE IF ISNULL({TEMP_PAY.ADD2}) THEN
NEXT({TEMP_PAY.ADD2})
ELSE IF ISNULL({TEMP_PAY.ADD3})THEN
NEXT({TEMP_PAY.ADD3})
ELSE IF ISNULL({TEMP_PAY.CITY})THEN
NEXT({TEMP_PAY.CITY})
ELSE IF ISNULL({TEMP_PAY.DIST})THEN
NEXT({TEMP_PAY.DIST})
ELSE
NEXT({TEMP_PAY.PIN})
Let me know if it helps

Calculate value based on existence of records matching given criteria - FileMaker Pro 13

How can I write a calculation field in a table that outputs '1' if there are other (related) records in the same table that meet a given set of criteria and '0' otherwise?
Here's my problem explained in more detail:
I have a table containing 'students' and another containing 'exam results'. The 'exam results' table looks like this:
StudentID SubjectID Level Result
3234 1 2 A-
3234 2 4 B+
4739 1 4 C+
A student can only pass a Level 4 exam in subject 2 if they have also passed a Level 2 exam in subject 1 with a B+ or higher. I want to define a field in the 'students' table that contains a '1' if there exists an exam result belonging to the right student that meets these criteria and a '0' otherwise.
What would be the best way to do this?
Let us take an example of a Results table where the results are also calculated as a numeric value, e.g.
StudentID SubjectID Level Result cResultNum
3234 1 2 A- 95
3234 2 4 B+ 85
4739 1 4 C+ 75
and an Exams table with the following fields (among others):
RequiredSubjectID
RequiredLevel
RequiredResultNum
Given these, you can construct a relationship between Exams and (another occurrence of) Results as:
Exams::RequiredSubjectID = Results 2::SubjectID
AND
Exams::RequiredLevel = Results 2::Level
AND
Exams::RequiredResultNum ≤ Results 2::cResultNum
This allows each exam record to calculate a list of students that are eligible to take that exam as =
List ( Results 2::StudentID )
I want to define a field in the 'students' table that contains a '1'
if there exists an exam result belonging to the right student that
meets these criteria and a '0' otherwise.
This request is unclear, because there are many exams a student may want to take, and a field in the Students table can calculate only one result.
You need to do a self-join in the table for the field you want to check, for example:
Exam::Level = Exam2::Level
Exam::Student = Exam2::Student
And for the "was passed" criteria I think you could do an "If" on the calculation like this:
If ( Last(Exam2::Result) = "D" and ...(all the pass values) ; 1 ; 0 )
Edit:
It could be just with the not pass value hehe I miss that it will be like this:
If ( Last(Exam2::Result) = "F" ; 0 ; 1 )
I hope this helps you.