How to apply where condition in each inner join in SQL Server - sql-server

I would like to apply conditions on each inner join like below
select *
from table1 table
inner join table2 t on t.column= table.column where condition
inner join table3 tb on tb.column = table.column where condition
But error is thrown on second where condition
Incorrect syntax near the keyword 'inner'.
Very new to joins in SQL Server. Any help please?

You need to put WHERE clauses at the end of the statement, but you can do this in an inner join like this:
select * from table1 table
inner join table2 t on t.column= table.column
and t.someColumn = 'SomeValue' --Here you can join on a condition
inner join table3 tb on tb.column = t.column
where <condition>
--Or...
select * from table1 table
inner join table2 t on t.column= table.column
inner join table3 tb on tb.column = t.column
where
t.column = 'blah'
and tb.column = 'blah2'

With an inner join all the conditions apply to the complete recordset. So you can just put them all in the where clause
select *
from table1 table
inner join table2 t on t.column= table.column
inner join table3 tb on tb.column = table.column
where condition1 and condition2
But for instance when using a left join the conditions only apply to the join itself. So you can use the on clause like this
select *
from table1 table
left join table2 t on t.column = table.column AND condition1
left join table3 tb on tb.column = table.column AND condition2

If you're looking to keep your main query clean, you can use a CTE to logically filter your table, away from your main query:
;with Employees as
(
select * from People where PersonType = 'Employee'
)
select * from ParkingSpots ps
join Employees e on ps.PersonID = e.PersonID

Related

Different Filters for Different Columns

I am relatively new to SQL and I have the following question. I have the following code:
Select * from table1
LEFT JOIN table2 ON table1.name = table2.name and table1.id = table2.id
LEFT JOIN (SELECT id FROM table2 GROUP BY id) newtable ON table1.id = newtable.id
As both left joins uses data from the same table, is it possible to combine the two joins into one? How would the filters work in this case?
If your goal just to join table2 based on distinct values, then you can use WHERE and GROUP BY:
Select
*
from table1 t1
LEFT JOIN table2 t2
ON t1.name = t2.name and t1.id = t2.id
WHERE t1 id in (SELECT s2.id FROM table2 s2 GROUP BY s2.id)

Conditional JOIN vs Self JOIN

I am trying to join two tables on two different columns and I was wondering if following two techniques are equivalent, if yes which one is better performance wise?
JOIN with OR (Conditional JOIN)
SELECT *
FROM table1
JOIN TABLE2 ON table1.value = table2.HighValue
OR table1.value = table2.LowValue
Using self Join
SELECT *
FROM TABLE1
JOIN table2 t2 ON table1.value = t2.HighValue
JOIN table2 t3 ON table1.value = t3.LowValue
The two queries are not equivalent, the first is equivalent to
SELECT *
FROM table1
JOIN TABLE2 ON table1.value = table2.HighValue
UNION
SELECT *
FROM table1
JOIN TABLE2 ON table1.value = table2.LowValue

UPDATE with SELECT with a reference to the updated table

I have a script:
UPDATE a
SET fieldX =
(SELECT F_Aggregate(x.fieldy)
FROM table_B
INNER JOIN ....
INNER JOIN ....
INNER JOIN ....
....
INNER JOIN table_C on .....
WHERE table_C.fieldY = table_A.fieldY)
FROM table_A a;
But now I want to update fieldX only when the select gives a different value. Like:
UPDATE a
SET fieldX =
(SELECT dbo.F_Aggregate(x.fieldy) as result
FROM table_B
INNER JOIN ....
INNER JOIN ....
INNER JOIN ....
....
INNER JOIN table_C on .....
WHERE table_C.fieldY = table_A.fieldY)
FROM table_A a
WHERE fieldX <> result;
I have found questions/answers that looks like this but they all have a select statement without a reference to the updated table.
Does anybody know a solution?
Move the calculation in other Data Source - it could be CTE, table variable or temporary table, etc. Then join the updated table with it:
WITH DataSource (fieldY, result) AS
(
SELECT table_C.fieldY
,dbo.F_Aggregate(x.fieldy) as result
FROM table_B
INNER JOIN ....
INNER JOIN ....
INNER JOIN ....
....
INNER JOIN table_C on .....
GROUP BY table_C.fieldY
)
UPDATE table_A
SET fieldX = result
FROM table_A A
INNER JOIN DataSource DS
ON A.[fieldY] = DS.[fieldY]
WHERE fieldX <> result

Use of CASE in a SQL query

I have a SQL query like this:
SELECT *
FROM table1
INNER JOIN table2 ON table1.key = table2.key
INNER JOIN table3 ON table1.var = table3.var
INNER JOIN table4 ON table1.field = table4.field
but I only want to include the table3 join if a variable has a certain value (iMarket=250 and above)
I'm trying to get this sort of condition working:
SELECT *
FROM table1
INNER JOIN table2 ON table1.key = table2.key
CASE
WHEN iMarket > 250
THEN INNER JOIN table3 ON table1.var = table3.var
END
INNER JOIN table4 on table1.field = table4.field
This is pseudo-code but it approximates to what I'm trying to do. Nothing works. Is there an easier way of doing it? I want to exclude this join because it always fails if that variable is below a certain value. Thank you all!
As easy to include condition in join on clause:
SELECT * from table1
INNER JOIN table2 on table1.key=table2.key
INNER JOIN table3 on iMarket>250 and table1.var=table3.var
INNER JOIN table4 on table1.field=table4.field
Remember than you should use outer joins if you need all values from other tables despite the fact that they are no matches for table3, perhaps you are looking for this behavior:
SELECT * from table1
INNER JOIN table2 on table1.key=table2.key
INNER JOIN table4 on table1.field=table4.field
left outer join --<--
table3 on iMarket>250 and table1.var=table3.var

Change Sql "Not In" To "Left Outer Join"

I don't want to use "not in" this sql query. How can I do it? thanks
SELECT
T2.Sno,
T2.Name,
T1.description,
T2.UserCode
FROM
Table1 AS T1 (nolock)
INNER JOIN T2 (nolock)
ON T1.UserCode = T2.UserCode
WHERE
g.xid= #p_xid
and T2.Sno not in (select Gid from T3 (nolock))
Assuming there is no row in T2 where Sno is null and in T3 where Gid is null:
SELECT
T2.Sno,
T2.Name,
T1.description,
T2.UserCode
FROM
Table1 AS T1 WITH (nolock)
INNER JOIN T2 WITH (nolock)
LEFT JOIN T3 WITH (NOLOCK)
ON T2.Sno = T3.Gid
ON T1.UserCode = T2.UserCode
WHERE
g.xid= #p_xid
and T3.Gid IS NULL
If you have multiple T3 rows per T2.Sno = T3.Gid, you'll need DISTINCT in a JOIN.
Without DISTINCT, it's a different query
With DISTINCT, it's an extra step.
I'd use NOT EXISTS which avoids this.
SELECT
T2.Sno,
T2.Name,
T1.description,
T2.UserCode
FROM
Table1 AS T1 (nolock)
INNER JOIN T2 (nolock)
ON T1.UserCode = T2.UserCode
WHERE
g.xid= #p_xid
and not exists (select * from T3 (nolock) where T3.Gid = T2.Sno)

Resources