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

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

Related

How to do recursive lateral join in PostgreSQL?

I have a treelike data structure Object -> package -> package -> .... -> package. I have a query over table containing the Objects and I need to check if the topmost parent has a value set or not.
using only with recursive CTE will just give me all the packages and I don't know which is the topmost parent for my current object. With lateral join i can make a query per row to check for value but I can't seem to find a way to make a query that would work like recursive lateral join.
The output of the query should be a table containing all the values of Object and a value from the topmost package.
Is there a way to do it purely in SQL or do I need to have some intermediate data processing on server side?
It's a bit unclear to me what you are trying to achieve, but:
I need to check if the topmost parent has a value set or not.
This can be done by "carrying" the root information through the recursion. In the root query of the CTE, you can select the attribute you want to make available to every level. In the recursive part you simply take the attribute from the parent.
Something along the lines:
with recursive all_packages as (
select t.*, p.some_column as root_value
from the_table t
where <condition to select the roots>
union all
select t.*, p.root_value
from the_table t
join all_packages p on p.some_id = t.some_parent_id
where p.root_value .... (do something with the root value)
)
select *
from all_packages;

OrientDB: Efficient way to select records with a value equal to the max of all such values?

I'm not sure how to do this without using a JOIN (which ODB doesn't have, of course). In "generic" SQL, you might do something like this:
Select * FROM table
INNER JOIN
(SELECT max(field) AS max_of_field, key FROM table GROUP BY key) sub
ON table.field = sub.max_of_field AND table.key = sub.key
Is there an efficient way to do this in ODB, using SELECT and/or MATCH?

Two filters on one column with respect to each other

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'

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.

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