If statement within an inner join - sql-server

Is there a way to have an if statement determine whether a join is necessary or not?
I need this because there are multiple foreign keys in the data I querying. if any of the foreign keys are null I need to change the SQL statement. I would like to write one statement that can be aware of any null values.
This is what I would like to do...
select a.*,b.* from table1 a inner join table2 b on a.id = b.id
if a.InspectorID is not null
{inner join table3 c on a.InspectionID = c.id}
else do nothing...

try this out...
select a.*,b.* from table1 a inner join table2 b on a.id = b.id
left join table3 c on a.InspectionID = c.id
where a.InspectorID is null or a.InspectionID = c.id

I am not sure, if you can conditionally join tables, but the "if" statement in t-sql is calles
case.

What about using union
select a.*,b.*
from table1 a
inner join table2 b on a.id = b.id
inner join table3 c on a.InspectionID = c.id
union all
select a.*,b.*
from table1 a
inner join table2 b on a.id = b.id
where a.InspectionID is null

If I understand correctly, you could use:
select a.*,b.*,c.fields
from table1 a inner join table2 b on a.id = b.id
left join table3 c on a.InspectionID = c.id
where a.InspectionID IS NOT NULL

Use dynamic sql. For detail about dynamic sql go through:
http://exacthelp.blogspot.in/2013/02/writing-dynamic-sql-queries-in-sql.html

Related

replace nested where condition with join

I have a SQL query that looks like this
Select a.*
From table1 a
where a.ColumnName in
(Select MAX(b.ColumnName)
from table2 b
where b.ColumnName2 in
(
Select MAX(c.columnName)
from table3 c
Group by c.ColumnName2
)
Group by b.ColumnName2
)
I am trying to write this in a join statement. I am positive inner join is what I need to get the right information. If someone could translate this to a join statement, I would be really glad.
Thank you.
EDIT 1:
I tried the typical Join statement that a rookie would.
Select a.*
from table1 a
inner join table2 b
on a.columnname = (Select max(b.columnName) from table2)
inner join table3 c
on b.columnName = (select max(c.columnName) from table3)
Obviously, that didn't work because I get 100,000+ results when I should be getting 800. I tried using an alias for table2 and table3 INSIDE the subselect statements and selecting the columnname using THAT alias like this:
Select max(bPart.columnName from table2 bPart)
Select max(cPart.columnName from table3 cPart)
Still the same result.
PERHAPS....
Though I'm not sure why a join is needed. Performance wise exists would likely be fastest, and since you're not returning values from table2 or 3 it seems like it would be the best approach.
SELECT a.*
FROM table1 a
INNER JOIN (SELECT MAX(ColumnName) MColumnName, columnname2
FROM table2
GROUP BY columnName2) B
ON A.columnName = B.mColumnName
INNER JOIN (SELECT MAX(columnName) mColumnName
FROM table3
GROUP BY ColumnName2) C
ON B.columname2 = C.MColumnName

How to apply where condition in each inner join in 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

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

SQL Server Select query is very slow. How can I get better result?

I've a very slow SQL query on SQL Server 2005. It takes almost 40 seconds just to do a select. After the select, I get result query and do an insert using this result. Every "textField" and "Id" is index unique and every "Id" is PK. Please what can I do to get better results? Thanks!
SELECT DISTINCT
C.Id, E.Id, B.Id, A.Id
FROM
tableA AS A
INNER JOIN
tableB AS B
INNER JOIN
tableC AS C
INNER JOIN
tableD AS D ON C.textField = D.textField
INNER JOIN
tableE AS E ON D.textField = E.textField
ON B.textField = D.textField
ON A.textField = D.textField
First off, your query is not optimized very well at all.
For your inner joins on tables A, B and C you should have some conditions on those joins or you will get a Cartesian product on those tables.
SELECT DISTINCT C.Id, E.Id, B.Id, A.Id
FROM tableA AS A INNER JOIN
tableB AS B **ON B.<fieldname> = <A.fieldname>** INNER JOIN
tableC AS C **ON C.<Fieldname> = <B.FieldName>** INNER JOIN
tableD AS D ON C.textField = D.textField INNER JOIN
tableE AS E ON D.textField = E.textField ON B.textField = D.textField ON A.textField

SQL Server Conditional JOIN two tables

I have 3 Tables:
TableA(IDRem, IDPed, IDOP)
TableB(IDOP, IDPed)
TableC(IDPed, InvoiceDate)
I need a select to JOIN the records of TableA and TableC, but there are two possible conditions:
IF IDPed on TableA IS NOT NULL, then join directly to TableC by IDPed
ID IDPed on TableA IS NULL, then join to TableB by IDOp, and then join TableB to TableC by IDPed
So far i try this:
SELECT
TableA.*
,(CASE WHEN TableC.InvoiceDate IS NULL
THEN TableC2.InvoiceDate
ELSE TableC.InvoiceDate
END) AS InvoiceDate
FROM
TableA
LEFT JOIN TableC on TableA.IDPed = TableC.IDPed
LEFT JOIN TableB on TableB.IDOp = TableA.IDOp
INNER JOIN TableC as TableC2 on TableC2.IDPed = TableB.IDPed
The problem with this is that every field o tableA I want to include in the select I need to do a case...when to determine if the origin is tableA or TableA2.
Is there a better way of doing this? Thanks!
For complex joins you are better served in TSQL using cross apply:
When should I use Cross Apply over Inner Join?
select IDRem, IDPed, IDOP from TableA a
cross apply(
select IDOP, IDPed from TableB binner
where a.IDop = binner.IDop
) b
cross apply(
select IDPed, InvoiceDate cinner
where b.IDPed = cinner.IDPed
) c
where ...
Strictly psuedo-code but should give you a start.
You could try doing both JOINs and use UNION ALL
Edit: As pointed out in the comment by Vladimir Baranov, there's no need to check if a.IdPed IS NULL on the first SELECT since if it is, the JOIN would return no rows.
SELECT
a.*,
c.InvoiceDate
FROM TableA a
INNER JOIN TableC c ON c.IdPed = a.IdPed
UNION ALL
SELECT
a.*,
c.InvoiceDate
FROM TableA a
INNER JOIN TableB b ON b.IdOp = a.IdOP
INNER JOIN TableC c ON c.IdPed = b.IdPed
WHERE a.IdPed IS NULL

Resources