How to create an exclusion filter set in Tableau - tableau-api

I am working in Tableau and trying to figure out how to create a filter exclusion. For example I have the following fields.
Hospital CallType CallDate
I want to filter out all hospitals where one of the Calls has a call type of ColdCall and a Call DateBetween X and Y.
I can do this easily in SQL but don't have access to this data in the SQL Database. It would be the following:
Select
Hospital
,CallType
,CallDate
Into
#TempTable
From
Database
Select
Hospital
,CallType
,CallDate
Into
#ExclusionTable
From
Database
Where
CallType = 'Cold'
and
CallDate Between X and Y
Select
Hospital
,CallType
,CallDate
From
#TempTable
Where
Hospital not in
(Select
Hospital
From
#ExclusionTable)
Any suggestions would be greatly appreciated.
Thanks,

Simple. Create a calculated field Filter:
IF CallType = "Cold" AND CallDate < X AND CallDate > Y
THEN 1
ELSE 0
END
Then drag Hospital to filter, go to Condition tab, select by field, get your Filter field, use sum > 0. It will filter out any hospital that have at least one call with your conditions (because all the calls that don't meet will be zero, and if at least one is not zero, the sum will be over 0)
For X and Y, I'd create parameters. It's easier (and safer) than trying to write the dates directly on the field. And you can manipulate then more easily too

Related

Removing Duplicates From Multiple Unique Columns

I am accessing table that takes in every encounter between two vehicles (i do not have permissions to change this table). When an encounter occurs, it'll take in one row for each perspective of the encounter- Vehicle X encountered Vehicle Y and another row for Vehicle Y encountered Vehicle X. Here's some sample data:
Location Vehicle1 Vehicle2
103923 5594800 54114
105938 40547 1855442
103923 2588603 5659158
103923 54114 5594800
103923 5659158 2588603
105938 1855442 40547
There are no duplicates in any row, values are all unique. But every value in Vehicle1 exists in vehicle2. How would i get it so only one of each pair exists?
GREATEST and LEAST functions might help.
DELETE ... USING syntax
DELETE
FROM t a USING
( SELECT location,
greatest(Vehicle1 , Vehicle2) as vehicle1,
least(Vehicle1 , Vehicle2) as vehicle2
FROM t
GROUP BY 1,2,3 HAVING COUNT(*) > 1 ) b
WHERE a.location = b.location
AND a.Vehicle1 = b.Vehicle1
AND a.Vehicle2 = b.Vehicle2;

How to do a one-to-many join with conditions in posgreql

Forgive me, I don't know how to ask this question and google for an answer. May have already been answered elsewhere on Stack, let me know if it is.
I want to use postgresql to join one table, Table A, with Table B such that the values in one set of columns in Table A are joined and multiplied (one-to-many join) by the corresponding values in a set of columns in Table B, based on whether the values in the set of columns in Table B are within the range of the values in the set of columns in Table A.
Basically:
Where Start_A >= Start_B AND End_A <= End_B
Like so:
i think this can help you. But in your quest and result where you question "Basically: Where Start_A >= Start_B AND End_A <= End_B", I think this your mistake because in result i saw Start_A <= Start_B AND End_A >= End_B. And id write the query for you:
SELECT *
FROM a LEFT JOIN b ON startA <= startB
WHERE endA >= endB

Tableau - Calculating average where date is less than value from another data source

I am trying to calculate the average of a column in Tableau, except the problem is I am trying to use a single date value (based on filter) from another data source to only calculate the average where the exam date is <= the filtered date value from the other source.
Note: Parameters will not work for me here, since new date values are being added constantly to the set.
I have tried many different approaches, but the simplest was trying to use a calculated field that pulls in the filtered exam date from the other data source.
It successfully can pull the filtered date, but the formula does not work as expected. 2 versions of the calculation are below:
IF DATE(ATTR([Exam Date])) <= DATE(ATTR([Averages (Tableau Test Scores)].[Updated])) THEN AVG([Raw Score]) END
IF DATEDIFF('day', DATE(ATTR([Exam Date])), DATE(ATTR([Averages (Tableau Test Scores)].[Updated]))) > 1 THEN AVG([Raw Score]) END
Basically, I am looking for the equivalent of this in SQL Server:
SELECT AVG([Raw Score]) WHERE ExamDate <= (Filtered Exam Date)
Below a workbook that shows an example of what I am trying to accomplish. Currently it returns all blanks, likely due to the many-to-one comparison I am trying to use in my calculation.
Any feedback is greatly appreciated!
Tableau Test Exam Workbook
I was able to solve this by using Custom SQL to join the tables together and calculate the average based on my conditions, to get the column results I wanted.
Would still be great to have this ability directly in Tableau, but whatever gets the job done.
Edit:
SELECT
[AcademicYear]
,[Discipline]
--Get the number of student takers
,COUNT([Id]) AS [Students (N)]
--Get the average of the Raw Score
,CAST(AVG(RawScore) AS DECIMAL(10,2)) AS [School Mean]
--Get the number of failures based on an "adjusted score" column
,COUNT([AdjustedScore] < 70 THEN 1 END) AS [School Failures]
--This is the column used as the cutoff point for including scores
,[Average_Update].[Updated]
FROM [dbo].[Average] [Average]
FULL OUTER JOIN [dbo].[Average_Update] [Average_Update] ON ([Average_Update].[Id] = [Average].UpdateDateId)
--The meat of joining data for accurate calculations
FULL OUTER JOIN (
SELECT DISTINCT S.[Id], S.[LastName], S.[FirstName], S.[ExamDate], S.[RawScoreStandard], S.[RawScorePercent], S.[AdjustedScore], S.[Subject], P.[Id] AS PeriodId
FROM [StudentScore] S
FULL OUTER JOIN
(
--Get only the 1st attempt
SELECT DISTINCT [NBOMEId], S2.[Subject], MIN([ExamDate]) AS ExamDate
FROM [StudentScore] S2
GROUP BY [NBOMEId],S2.[Subject]
) B
ON S.[NBOMEId] = B.[NBOMEId] AND S.[Subject] = B.[Subject] AND S.[ExamDate] = B.[ExamDate]
--Group in "Exam Periods" based on the list of periods w/ start & end dates in another table.
FULL OUTER JOIN [ExamPeriod] P
ON S.[ExamDate] = P.PeriodStart AND S.[ExamDate] <= P.PeriodEnd
WHERE S.[Subject] = B.[Subject]
GROUP BY P.[Id], S.[Subject], S.[ExamDate], S.[RawScoreStandard], S.[RawScorePercent], S.[AdjustedScore], S.[NBOMEId], S.[NBOMELastName], S.[NBOMEFirstName], S.[SecondYrTake]) [StudentScore]
ON
([StudentScore].PeriodId = [Average_Update].ExamPeriodId
AND [StudentScore].Subject = [Average].Subject
AND [StudentScore].[ExamDate] <= [Average_Update].[Updated])
--End meat
--Joins to pull in relevant data for normalized tables
FULL OUTER JOIN [dbo].[Student] [Student] ON ([StudentScore].[NBOMEId] = [Student].[NBOMEId])
INNER JOIN [dbo].[ExamPeriod] [ExamPeriod] ON ([Average_Update].ExamPeriodId = [ExamPeriod].[Id])
INNER JOIN [dbo].[AcademicYear] [AcademicYear] ON ([ExamPeriod].[AcademicYearId] = [AcademicYear].[Id])
--This will pull only the latest update entry for every academic year.
WHERE [Updated] IN (
SELECT DISTINCT MAX([Updated]) AS MaxDate
FROM [Average_Update]
GROUP BY[ExamPeriodId])
GROUP BY [AcademicYear].[AcademicYearText], [Average].[Subject], [Average_Update].[Updated],
ORDER BY [AcademicYear].[AcademicYearText], [Average_Update].[Updated], [Average].[Subject]
I couldn't download your file to test with your data, but try reversing the order of taking the average ie
average(IF DATE(ATTR([Exam Date])) <= DATE(ATTR([Averages (Tableau Test Scores)].[Updated]) then [Raw Score]) END)
as written, I believe you'll be averaging the data before returning it from the if statement, whereas you want to return the data, then average it.

Postgresql upper limit of a calculated field

is there a way to set an upper limit to a calculation (calculated field) which is already in a CASE clause? I'm calculating percentages and, obviously, don't want the highest value exceed '100'.
If it wasn't in a CASE clause already, I'd create something like 'case when calculation > 100.0 then 100 else calculation end as needed_percent' but I can't do it now..
Thanks for any suggestions.
I think using least function will be the best option.
select least((case when ...), 100) from ...
There is a way to set an upper limit on a calculated field by creating an outer query. Check out my example below. The inner query will be the query that you have currently. Then just create an outer query on it and use a WHERE clause to limit it to <= 1.
SELECT
z.id,
z.name,
z.percent
FROM(
SELECT
id,
name,
CASE WHEN id = 2 THEN sales/SUM(sales) ELSE NULL END AS percent
FROM
users_table
) AS z
WHERE z.percent <= 1

How to write date filter in MDX where clause?

I am new to MDX. Could please suggest how to write below T-SQL query in MDX Query language.
T-SQL:
SELECT wp.date,Sum(wp.bbls_oil)
AS BBLSOIL_TOTAL,Sum(wp.bbls_water)
AS BBLSWATER_TOTAL,Sum(wp.mcf_prod)
AS MCF_PROD_TOTAL,Sum(wp.vent_flare)
AS VENT_FLARE_TOTAL
FROM well_prod_bst_horiz_og_2_yrs wp, well_index wi
WHERE wp.fileno = wi.fileno
AND wp.date <= :startDate
AND wp.date >= :endDate
AND wi.apino IN (:wellids)
GROUP BY wp.date ORDER BY wp.date ASC";
In the above query, Start and End date values are supplied dynamically.
Assuming you have measures named BBLSOIL, BBLSWATER, MCF_PROD, and VENT_FLARE_TOTAL and your date attribute is named [Date].[Date], and your :startDate contains [Date].[Date].&[20120101] and your :endDate contains [Date].[Date].&[20141231], and your cube is named Name of your Cube you would write
SELECT {
Measures.[BBLSOIL],
Measures.[BBLSWATER],
Measures.[MCF_PROD],
Measures.[VENT_FLARE_TOTAL]
}
ON COLUMNS,
[Date].[Date].&[20120101] : [Date].[Date].&[20141231]
ON ROWS
FROM [Name of your Cube]
i. e. you put an MDX set containing the list of required measures on the columns axis and you put a range (specified by :) on the rows axis. Aggregations like Sum and GROUP BY are not necessary inn MDX, these are handled by the cube definition.