Two filters on one column with respect to each other - tableau-api

I would like to filter my data source by itself. In SQL it is just INNER JOINNING a table by itself.
For example,
SELECT table1.*
FROM table1 INNER JOIN (SELECT id FROM table1 WHERE variable = ‘X’ AND value = 1) q1 ON table1.id = q1.id
WHERE table1.variable = ‘Y’
As you can see I want to present only the variable which equals ‘Y’ with respect to variable =’X’ and value=1.
I can also write it like this,
SELECT *
FROM table1
WHERE variable = ‘Y’ AND id IN (SELECT id FROM table1 WHERE variable = ‘X’ AND value = 1)
I am using a long data file which means my primary key is 'id' and 'variable' together. So, I want all the variable = ‘Y’ data to be presented only if the 'id' has variable = ‘X’ AND value = 1. How do I translate this process in Tableau dashboard?
Any suggestions on how to do it without inner joining the data source by itself? I tried the inner join way but my data is very large which resulting in too much processing time and it makes all the other processes extremely slow.

First, just point your data source at table1 without any other changes. Plain and simple.
Second, back on a worksheet, select the id field in the datapane and right click to create a set. Choose the all radio button on the general tab of the set dialog pane, and then switch to the condition tab. Define the set via the formula max(variable = 'x' and value = 1). Call your set something meaningful like ids_having_an_X1. This will create a set of ids that have at least one data row matching your condition. Think of it as a list of ids that could go inside a SQL IN (...) clause if that helps
Now you can use your set on the filter shelf to only include those ids in the query, or in calculations, or on other shelves.
To get the effect of your where clause, put variable on the filter shelf choosing only the value 'Y'

Related

How do you pass a column value to a function that returns a table

I have a stored procedure that takes an int and returns a table that's used in a left join. I'd like to create a view instead of calling the procedure. Is there any way to do this? I'm getting "multi-part identifier couldn't be bound"
Example:
select users.*, extended.*
from users left join dbo.getaggregateproperties(users.Id) as extended
on users.userid = extended.extendedid
Use CROSS APPLY instead
SELECT users.*, extended.*
FROM users
CROSS APPLY dbo.getaggregateproperties(users.Id) as extended
WHERE users.userid = extended.extendedid

Transpose/Pivot a table in Postgres

I am trying for hours to transpose one table into another one this way:
My idea is to grab on an expression (which can be a simple SELECT * FROM X INNER JOIN Y ...), and transpose it into a MATERIALIZED VIEW.
The problem is that the original table can have an arbitrary number of rows (hence columns in the transposed table). So I was not able to find a working solution, not even with colpivot.
Can this ever be done?
Use conditional aggregation:
select "user",
max(value) filter (where property = 'Name') as name,
max(value) filter (where property = 'Age') as age,
max(value) filter (where property = 'Address') as addres
from the_table
group by "user";
A fundamental restriction of SQL is, that all columns of a query must be known to the database before it starts running that query.
There is no way you can have a "dynamic" number of columns (evaluated at runtime) in SQL.
Another alternative is to aggregate everything into a JSON value:
select "user",
jsonb_object_agg(property, value) as properties
from the_table
group by "user";

Updating for each row in a table

I have this query here which returns an error because of too many rows returned:
UPDATE tmp_rsl2 SET comm_percent=( SELECT c2.comm_percent
FROM tmp_rsl2 t1
INNER JOIN gn_salesperson g1 ON t1.sales_person=g1.sales_person
INNER JOIN comm_schema c1 ON g1.comm_schema=c1.comm_schema
INNER JOIN comm_schema_dt c2 ON c1.comm_schema_id=c2.comm_schema_id AND (t1.balance_amount::numeric <= (COALESCE(c2.value_amount,0)) );`
Basically for each row of the comm_percent column, I want to update all of them using the subquery SELECT statement. I imagine using a FOR loop or something but I'd like to hear ideas or to know a proper way to do this.
The error TOO_MANY_ROWS is about assigning a value to a variable, that can only take '1' (one) value, whereas the SELECT query is returning more than one.
Without a reference schema, its difficult to give an SQL that'd work (not to say that the issue lies with the Schema), but you need to ensure that the value assigned to comm_percent from the SELECT statement returns only 1 row. A very blind attempt at how it 'might' work in your case (given below), but again without knowing the schema its difficult to gauge whether it'd work.
UPDATE tmp_rsl2
SET comm_percent = c2.comm_percent
FROM gn_salesperson g1 ON
INNER JOIN comm_schema c1 ON g1.comm_schema = c1.comm_schema
INNER JOIN comm_schema_dt c2 ON c1.comm_schema_id = c2.comm_schema_id
AND (tmp_rsl2.balance_amount::NUMERIC <= (COALESCE(c2.value_amount, 0)))
WHERE tmp_rsl2.sales_person = g1.sales_person
UPDATE
As per below comments, have given an unrelated SQLFiddle example that should give an idea of how to perform an UPDATE of all rows of a table looking up corresponding values from another table.

differing column names in self-outer-joins

When writing a self-join in tSQL I can avoid duplicate column names thus:
SELECT FirstEvent.Title AS FirstTitle, SecondEvent.Title AS FirstTitle
FROM ContiguatedEvents AS FirstEvent
LEFT OUTER JOIN ContiguatedEvents AS SecondEvent
ON FirstEvent.logID = SecondEvent.logID
Suppose I want to select all the columns from the self-join, for example into a view. How do I then differentiate the column names without writing each one out in the join statement. I.e. is there anything I can write like this (ish)
SELECT FirstEvent.* AS ???, SecondEvent.* AS ???
FROM ContiguatedEvents AS FirstEvent
LEFT OUTER JOIN ContiguatedEvents AS SecondEvent
ON FirstEvent.logID = SecondEvent.logID
There's no way to automatically introduce aliases for multiple columns, you just have to do it by hand.
One handy hint for quickly getting all of the column names into your query (in management studio) is to drag the Columns folder from the Object Explorer into a query window. It gives you all of the column names.

a dual variable not in statement?

I have the need to look at two tables that share two variables and get a list of the data from one table that does not have matching data in the other table. Example:
Table A
xName
Date
Place
xAmount
Table B
yName
Date
Place
yAmount
I need to be able to write a query that will check Table A and find entries that have no corresponding entry in Table B. If it was a one variable issue I could use not in statement but I can't think of a way to do that with two variables. A left join also does not appear like you could do it. Since looking at it by a specific date or place name would not work since we are talking about thousands of dates and hundreds of place names.
Thanks in advance to anyone who can help out.
SELECT TableA.Date,
TableA.Place,
TableA.xName,
TableA.xAmount,
TableB.yName,
TableB.yAmount
FROM TableA
LEFT OUTER JOIN TableB
ON TableA.Date = TableB.Date
AND TableA.Place = TableB.Place
WHERE TableB.yName IS NULL
OR TableB.yAmount IS NULL
SELECT * FROM A WHERE NOT EXISTS
(SELECT 1 FROM B
WHERE A.xName = B.yName AND A.Date = B.Date AND A.Place = B.Place AND A.xAmount = B.yAmount)
in ORACLE:
select xName , xAmount from tableA
MINUS
select yName , yAmount from tableB