I was trying to write a query with inner join only if RepID of Table1 exists in Table2, if not do not join table2. With the query that i used below, i do not get from both the tables if repID doesnot exist in Table2. How is it possible? I am using sql server 2005. Thank you in advance!
Select * from Table1
inner join Table2 on Table1.RepID = Table2.RepID
where Table1.Date = #Date
order by Table1.Date desc
An inner join will only return a row if matches are found in both sides of the join. If you're looking for something that will return all rows from Table1 but only records from Table2 when a match is found, you want a left outer join:
select * from Table1 as t1
left outer join Table2 as t2
on t1.RepID = t2.RepID
where t1.Date = #Date
order by t1.Date desc
Try "LEFT JOIN" instead of "INNER JOIN".
The word "LEFT" means "Always include every record from the table on the LEFT of the join," in this case Table1, since you will write: Table1 LEFT JOIN Table2, and "Table1" is on the left of that pair! :-)
it sounds like what you actually want is a left outer join, isnt it?
SELECT *
FROM Table1
LEFT JOIN Table2
ON Table1.RepID = Table2.RepID
WHERE Table1.Date = #Date
ORDER BY Table1.Date DESC;
That's what outer joins are for.
Select * from Table1
left outer join Table2 on Table1.RepID = Table2.RepID
where Table1.Date = #Date
order by Table1.Date desc
Related
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.
I've got 3 tables that I want to join and filter on some conditions.
I've first wrote this query:
select * from table1 t1
left join (select * from table2 where table2.fieldX=...) t2
on t1.id_12=t2.id_12
left join table3
on t2.id_23=t3.id_23
where t1.fieldY=...
Then I wanted to make it looks like more canonical by rewritting it like that:
select * from table1 t1
left join table2 t2
on t1.id_12=t2.id_12
left join table3
on t2.id_23=t3.id_23
where table2.fieldX=...
and t1.fieldY=...
But it does not give the same result.
I dont't understand why...
Do you?
Thanks in advance.
When you put table2.fieldX=... in the where clause you eliminate all rows from table1 that do not have a corresponding row in table2. Effectively you are changing the left join into an inner join.
Instead, you can apply the table2 filter in the join itself:
SELECT
*
FROM
Table1 t1
LEFT JOIN Table2 t2 ON t1.id_12 = t2.id_12 AND t2.fieldX = ...
LEFT JOIN Table3 t3 ON t2.id_23 = t3.id_23
WHERE
t1.fieldY = ...
Did you add the inner select where on the second query?
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
on t1.id_12=t2.id_12
LEFT JOIN table3
on t2.id_23=t3.id_23
WHERE t1.fieldY=...
and t2.fieldX=...
I have three tables and two seperate SQL queries which are working correctly and I am having correct results.
If I try to join these three tables I am having null as result.
First query:
select T1.ID,T3.COMPANY
from T1,T3
where (T1.status!='CLOSED') and (T1.PRIORITY)>5 and T1.CLASSID=T3.CLASSID
Second query:
SELECT T1.ID, T2.DESCRIPTION
FROM T1
LEFT OUTER JOIN T2
ON T1.ID=T2.KEY
WHERE T1.status!='CLOSED'
AND (T2.CREATEDATE= (SELECT MAX(CREATEDATE)
FROM T2
WHERE T2.KEY=T1.ID))
I tried to join them but as result I am having null:
select T1.ID,T3.COMPANY,T2.DESCRIPTION
from T1
INNER JOIN T3 ON T1.CLASSID=T3.CLASSID
LEFT OUTER JOIN T2
ON T1.ID=T2.KEY
where (T1.status!='CLOSED') AND (T1.PRIORITY)>5
AND (T2.CREATEDATE= (SELECT MAX(CREATEDATE)
FROM T2
WHERE T2.KEY=T1.ID))
like it does not recognized last part for taking MAX value from T2 table.
What am I doing wrong? Thanks for help
Firstly, use an alias for the subquery on table T2.
T2.CREATEDATE =
(SELECT MAX(T2Alias.CREATEDATE)
FROM T2 AS T2Alias
WHERE T2Alias.KEY = T1.ID)
Secondly, consider moving this condition into the ON clause of the LEFT JOIN to table T2.
The first thing that jumps out at me is the new dependency on both T1.Priority > 5 and T2.CreateDate value being equal to the result of the inline query:
( AND (T1.PRIORITY) > 5
AND (T2.CREATEDATE =
(SELECT MAX(CREATEDATE) FROM T2 WHERE T2.KEY = T1.ID) )
Without the data it's difficult to check however this may be the issue
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
Is there any way I can do a join between two tables where the resulting table has only the columns of the left table without the need to discriminate all the columns names in the select?
You can do this:
Select LeftTable.*
From LeftTable
Inner Join RightTable
On LeftTable.Id = RightTable.Id
Select T.* from tbl1 T, tbl2 J
You mean something like
Select t1.id, t1.name, t1.age FROM t1 INNER JOIN t2 ON t1.id = t2.id
WHERE t2.Something = Something