Need assistance with Left Outer join? - sql

SELECT ID
(
Select ID from Table1
where Table1.ID=#ID
)T1
Left Outer join
(
Select top 1 Table2.ID from Table2 join Table3 on table3.ID=Table2.ID
order by Table2.ID DESC
)T2 on T2.ID=T1.ID
This is just an example of the actual stored procedure I have with me, the problem which I am facing is that I'm unable to retrieve the values from T2 it just returns as NULL but when I change it Top 5 i am able to retrieve the values. Is this Join correct, is it necessary to have where part inside left outer join in order to retrieve the values?

If you are using TOP you need to decide on all selects (all three) how your data should be ordered so you can have some control on which values you are getting back, and maybe also being more specific on what you filter.

A couple of observations.
There's no ORDER BY clause for your T1 SELECT, so how do you know which TOP 250 is being returned?
If T2 returns NULL, then there is no match between T1 and T2, possibly due to my first point?

What exactly are you trying to accomplish?
You could try something like this:
SELECT
TOP 250 Table1.ID
FROM
Table1
LEFT OUTER JOIN
Table2 ON Table2.ID = Table1.ID
LEFT OUTER JOIN
Table3 ON Table3.ID = Table2.ID
WHERE
Table1.ID = #ID
ORDER BY
Table1.ID DESC

Related

SQL Join tables with empty values

I have 2 tables
Lets say Table1 and Table2
They both have one shared value(id)
What I'm looking for is whether there is any function to combine them both based on that key, however if table2 has more elements, i want columns of table1 to be empty, and if table1 has more elements, table 2 columns to be empty
I tried a lot of different joins, but most of the time I end up with a lot of duplicate values as it tries to fill in both sides.
Tried Full outer join, Full join, etc
You are looking for full join:
select t1.*, t2.*
from t1 full join
t2
on t1.id = t2.id;
The above code from Gordon is right. However, since you have not specified the database and its version, I will post an alternate version for MySQL, which should also work for other databases.
Without duplicates:
SELECT * FROM Table1
LEFT JOIN Table2 ON Table1.id = Table2.id
UNION
SELECT * FROM Table1
RIGHT JOIN Table2 ON Table1.id = Table2.id
With duplicates:
SELECT * FROM Table1
LEFT JOIN Table2 ON Table1.id = Table2.id
UNION ALL
SELECT * FROM Table1
RIGHT JOIN Table2 ON Table1.id = Table2.id

JOIN and SELECT values not included in table2

I appreciate this might be very simple for you guys but sometimes the logic behind JOIN can be difficult for beginners. I want to select "ID" from table1 but only those "ID"s which do NOT appear in table2."ID". I tested LEFT and RIGHT but cannot get it to work the way I need to. I am using dashDB.
You can use NOT IN and subquery
Select * from table1 where id NOT IN (select id from table2);
try this...
SELECT *
FROM table1
LEFT JOIN table2 ON table1.ID = table2.ID
WHERE table2.ID IS NULL
I always prefer NOT EXISTS to do this
Select * from table1 a
where NOT EXISTS (select 1 from table2 b where a.id = b.id);
Here is a excellent article by Aaron Bertrand that compares the performance of all the methods
Should I use NOT IN, OUTER APPLY, LEFT OUTER JOIN, EXCEPT, or NOT EXISTS?
Use the below script.
SELECT t1.ID
FROM table1 t1
LEFT JOIN table2 t2 ON t1.ID = t2.ID
WHERE t2.ID IS NULL

One update SQL query from three tables

I have three tables and I have to write one query to update table 1 row from table 3 and the only matching columns I have is in table 2.
Table 1 which has incorrect data:
Table 3 has the correct data:
I did try to write a query and execute it but it gives me an error saying there are too many rows too select which is true I do have many rows to correct but it still wouldn't correct. What do you think I should do. This is my query so far.
UPDATE Table1
SET Table1.Number = (SELECT Table3.Number
FROM Table2
FULL OUTER JOIN Table1 ON Table1.ID = Table2.ID
FULL OUTER JOIN Table3 ON Table3.Signin = Table2.Signin
WHERE (Table2.ID = Table1.ID)
AND (Table1.Number = 'xxx'))
WHERE (Tale1.Number = 'xxx')
In Where clause of JOIN query need to modify as multiple records are generating by inappropriate condition.Try to use Table3 components instead of using Table1 in joining query where clause.
UPDATE Table1
SET Table1.NUMBER = (SELECT table3.NUMBER FROM Table1 FULL OUTER JOIN Table2
ON Table1.ID = Table2.ID
FULL OUTER JOIN Table3
ON Table2.SIGNIN = Table3.SIGNIN
WHERE Table3.SIGNIN = 100) // This is the point where you need to modify your code
WHERE Table1.ID = 1;
ONLINE DEMO HERE
It actually worked after I removed this line from my query.
FULL OUTER JOIN Table1 ON table1.ID = Table2.ID
Thanks for the help.
You are fairly close. When doing the update though unless you are wanting to clear value for t1.number when a record is not matched in t3, you will want to use INNER JOIN. FULL OUTER JOIN would mean you are trying to update rows in t1 that don't exist but a LEFT JOIN you would update t1.number to NULL if a record in t3 doesn't exist.
UPDATE t1
SET t1.Number = t3.Number
FROM
Table1 t1
INNER JOIN Table2 t2
ON t1.Id = t2.Id
INNER JOIN Table3 t3
ON t2.Signin = t.3.Signin
WHERE
t1.number <> t3.number
--Or if you have nulls something like
--ISNULL(t1.number,'xxx') <> ISNULL(t3.number,'xxx')
-- if you only want to update when t1.number = 'xxx' then
--t1.number = 'xxx'
t1,t2,t3 are table aliases that I created by adding the alias after table name. By using join syntax rather than a sub select you simplify your were conditions. In sql-sever if more than 1 record in t2 & t3 match it will select one row randomly in the case of a one to many relationship. If you want a specific record when not one to one relation you can use window functions and common table expressions (cte) to limit t3 to the exact record you want to use.

Outer Join 3 Tables in Rails

I have 3 models. Table1 belongs to Table2, and Table2 belongs to Table3.
I want to get an ActiveRecord::Relation that includes all of the fields from all 3 tables, including nulls (outer joining to get all of Table1), with a WHERE clause on Table1 and an order by a column in Table3.
What I want in SQL is:
SELECT * FROM Table1 LEFT OUTER JOIN Table2 ON Table2.id = Table1.table2_id
LEFT OUTER JOIN Table3 ON Table3.id = Table2.table3_id
WHERE Table1.column1 = "example"
ORDER BY Table3.table3_column
However, I have been trying for hours now to do this in rails and getting nowhere. Is it possible?
#records = Table1.joins(:table2).joins(:table3).where(:column1 => "example").order("table3_column")
(For example), gets me nowhere because it is looking for an association between Table1 and Table3, which doesn't exist other than through Table2. I need to join once, then join on top of that. Not to mention that is an inner join. I've tried of the form:
#records = Table1.joins("LEFT OUTER JOIN Table2 ON Table2.id = Table1.table2_id LEFT OUTER JOIN Table3 ON Table3.id = Table2.table3_id")
But I get nil from that.
Thanks for any help with this.
Try find_by_sql
Table1.find_by_sql("SELECT * FROM Table1
LEFT OUTER JOIN Table2 ON Table2.id = Table1.table2_id
LEFT OUTER JOIN Table3 ON Table3.id = Table2.table3_id
WHERE Table1.column1 = "example"
ORDER BY Table3.table3_column")
refer find by sql

Selecting records based on two other tables

I have a query with inner join to another table, with this I want also include records which are contained in another column.
Example:
select name, address from table1
inner join table2 on table1.id = table2.id
With this, I want to also include rows which are having table1.recno = (1,2,4).
How could I write query for that?
One option I know is to use the IN keyword instead of the first table join. But our client doesn't want to use the IN keyword.
Use a left join and then use the WHERE clause to filter out the rows that you need.
select name, address
from table1
left join table2 on table1.id = table2.id
where
table2.id IS NOT NULL OR table1.ID In (1,2,4)
Or if you want to avoid an innocuous IN for silly reasons, use:
select name, address
from table1
left join table2 on table1.id = table2.id
where
table2.id IS NOT NULL
OR table1.ID = 1
OR table1.ID = 2
OR table1.ID = 4