MS SQL Server trouble with JOIN - sql-server

I'm new to SQL and need a push in the right direction.
I currently have a working SQL query accessing 3 tables in a database, and I need to add a JOIN using a 4th table, but the syntax escapes me. To simplify, what I have now is:
SELECT
t1_col1, t1_col2, t2_col1, t2_col2, t3_col1
FROM
table1, table2, table3
WHERE
{some conditions}
ORDER BY
t1_col1 ASC;
What I need to do is to add a LEFT OUTER JOIN selecting 2 columns from table4 and have ON t1_field1 = t4_field1, but whatever I try, I'm getting syntax errors all over the place. I don't seem to understand the correct syntax.
I tried
SELECT *
FROM table1
LEFT OUTER JOIN table2;
which has no errors, but as soon as I start SELECTing columns and adding conditions, I get stuck.
I would greatly appreciate any assistance with this.

You do not specify the join criteria. Those would be in your WHERE clause under "some conditions". So, I will make up so that I can show syntax. The syntax you show is often termed "old". It has been discouraged for 15 years or more in the SQL Server documentation. Microsoft consistently threatens to stop recognizing the syntax. But, apparently they have not followed through on that threat.
The syntax errors you are getting occur because you are mixing the old style joins (comma separated with WHERE clause) with the new style (LEFT OUTER JOIN) with ON clauses.
Your existing query should be changed to something like this. The tables are aliased because it makes it easier to read and is customary. I just made up the JOIN criteria.
SELECT t1_col1, t1_col2, t2_col1, t2_col2, t3_col1
FROM table1 t1
INNER JOIN table2 t2 ON t2.one_ID = t1.one_ID
INNER JOIN table3 t3 ON t3.two_ID = t2.two_ID
LEFT OUTER JOIN table4 t4 ON t4.three_ID = t3.three_ID
I hope that helps with "a push in the right direction."

You may also want to read this post that explains the different ways to join tables in a query. What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?
Also for the record the "OLD STYLE" of joining tables (NOT RECOMMENDED) would look like this (but do NOT do this - it is a horrible way to write SQL). And it does not work for left outer joins. Get familiar with using the ...JOIN...ON... syntax:
SELECT t1_col1, t1_col2, t2_col1, t2_col2, t3_col1
FROM table1 t1, table2 t2, table3 t3
LEFT OUTER JOIN table4 t4 ON t4.three_ID = t3.three_ID
WHERE
t2.one_ID = t1.one_ID
AND t3.two_ID = t2.two_ID

Related

How can I get 3 tables INNER JOIN in MS SQL Server

From the specialist table, retrieve the first name, last name and contact number for the people that provide care to penguins from the species table.
There are 3 tables: tbl_specialist, tbl_species, tbl_care
I need help trying to INNER JOIN the tables to display First, Last, And Contact for penguins.
SELECT specialist_fname, specialist_lname, specialist_contact
FROM ((tbl_specialist
INNER JOIN tbl_species ON species_care = tbl_species.species_care)
INNER JOIN tbl_care ON care_id = tbl_care.care_id)
WHERE species_name = 'penguin'
;
It's a bit difficult without seeing the exact schema of the tables, but your syntax for the subquery is a bit off and you need to alias columns that are found in multiple tables in a JOIN statment. Try rewriting your SQL like this:
SELECT spl.specialist_fname, spl.specialist_lname, spl.specialist_contact
FROM tbl_specialist spl
INNER JOIN tbl_species s
ON spl.species_care = s.species_care
INNER JOIN tbl_care c
ON s.care_id = c.care_id
WHERE s.species_name = 'penguin'
I'm obviously inferring which tables certain columns come from in the join, but hopefully you get the idea.
I figured it out thank you.
SELECT specialist_fname, specialist_lname, specialist_contact
FROM ((tbl_specialist
INNER JOIN tbl_care ON tbl_care.care_specialist = tbl_specialist.specialist_id)
INNER JOIN tbl_species ON tbl_species.species_care= tbl_care.care_id)
WHERE species_name = 'penguin'
;

I want to know why merge join cannot be done without equal sign(=) on ON clause in SQL Server

I'm recently studying SQL Server. I read a book and it says that merge join requires at least one equal sign(=) on ON clause in SQL Server.
So, I tried this query below and I found that the error occurs.
SELECT *
FROM TABLE_1 AS T1
INNER MERGE JOIN TABLE_2 AS T2
ON T1.COL_1 > T2.COL_2
Error Message:
Msg 8622, Level 16, State 1, Line 6 Query processor could not produce
a query plan because of the hints defined in this query. Resubmit the
query without specifying any hints and without using SET FORCEPLAN.
And this book also says this can be done in case of Full Outer Join.
So I tried this query below and found it committed successfully with no errors.
SELECT *
FROM TABLE_1 AS T1
FULL OUTER MERGE JOIN TABLE_2 AS T2
ON T1.COL_1 > T2.COL_2
I tried to search for the reason but I couldn't find any explanation about this.
Can anyone tell me why SQL Server doesn't allow merge join without an equality operator unless it's full outer join?
Thank you for reading my question
You used Inner Merge Join. Merge clause is a join hint that tells sql engine to work more efficient.
Merge joins have the fastest algorithm since each row only needs to be read once from the source inputs. Also, optimizations occurring in other join operators can give those operators better performance under certain conditions.
if you must use '>' operator, use regular Inner Join, like this.
SELECT *
FROM TABLE_1 AS T1
INNER JOIN TABLE_2 AS T2
ON T1.COL_1 > T2.COL_2

Custom order for multiple joins in SQL Server

I am trying to write a query in SQL Server that replicates following figure:
I want the result of first left join (order_defect & ncdef) to be left join with third table (filter) and again the result of these three left join with last one (nsdic).
Each of these tables are huge, so I'm trying to find most efficient way to do it because i have limited space and I get "out of memory" error... any suggestion for an efficient query?
If I do:
Select *
from A
left join B on a.id = B.id
left join C on a.id = c.id
it's joining A and B first and then A and C...but I want the result of "A & B" to be join with "C".
Basically my question is how to use a result of one join, to join with another table.
Thank you
select
c.id
,c.colum1
,c.colum2
,c.colum3
,c.colum4
,t3.colum1
from
(
select
t1.id as id
,t1.colum1 as colum1
,t1.colum2 as colum2
,t2.column1 as colum3
,t2.colum2 as colum4
from table1 t1
left join table2 t2
on t1.id = t2.id
) as c
left join table3 t3
on c.id = t3.id
It's dificult to help you without the tables design and fields|columns, keys, ...
But I'll considerate:
1 - Primary keys fields, and how to relation the tables
2 - How to add left joins with "filters", or how to reduce the number of results
3 - Evaluate if it'll be better to use Sub-querys
Plus: Try the query with TOP 100 <--- to make test.
And remember: sometimes it's imposible to optimizate querys because of the hardware limits, like the RAM, in those case you have to show the data in sections.

SQL INNER JOIN vs LEFT JOIN with a WHERE

I am trying to grasp SQL joins more intuitively. For example, learning how a RIGHT JOIN can just be re-written as a LEFT JOIN (by flipping the order of the tables) helped me understand much better the way that the two joins work.
However, now I'm wondering if an INNER JOIN could be re-written as a LEFT JOIN with a WHERE condition- meaning that their logic could be equivalent (by "logic" I do not mean the execution plan, but the way that the intended result set would be described).
Like:
SELECT * FROM HeaderTable
INNER JOIN DetailTable
ON HeaderTable.ID = DetailTable.ParentID
Which I would read as "Show me all the records from tables HeaderTable and DetailTable that have a matching value in the HeaderTable.ID and DetailTable.ParentID fields." Being the same as:
SELECT * FROM HeaderTable
LEFT JOIN DetailTable
ON HeaderTable.ID = DetailTable.ParentID
WHERE HeaderTable.ID = DetailTable.ParentID
Which I would read as "Show me all the records from tables HeaderTable and DetailTable where the value of HeaderTable.ID is the same as the value of DetailTable.ParentID."
Will these return the same result set? I am more asking about the logic being the same as opposed to one being more efficient than the other.
If I may ask, please don't answer with any Venn diagrams as these don't seem to describe the logic of a join exactly to me.
Yes, they will return the same result. The left join without the where clause would read as show me all the records from the header table and the related items from the details table or null for the details where there are no matches.
Adding a where clause relating the ids effectively transforms the left join to an inner join by eliminating the non-matching rows that would have shown up as having null for the detail part.
In some databases, like MS SQL Server, the left join would show up as an inner join in the query execution plan.
Although you stated that you don't want Venn diagrams I can't help referring you to this question and its answers even though they are filled with (in my opinion very helpful) Venn diagrams.
Yes they would return the same result.
But then you could simply write
SELECT *
FROM HeaderTable, DetailTable
WHERE HeaderTable.ID = DetailTable.ParentID
this returns the same result as well. This is an old syntax used before the join-clauses were introduced.
On a left join if you reference the left in the where then you negate the left and turn it into regular join

Mixed JOIN and COMMA table listing in FROM; meaning of listed items

Ok, I currently tasked with maintaining a legacy SQL Server 2005 database recently migrated to 2008 [R2] and there are some sprocs with something like the following:
SELECT
#val = c.TableVal
FROM
dbo.TaqbleA a
LEFT JOIN dbo.TableB b
ON a.TableId = b.TableId
,dbo.TableC c
WHERE
a.TableId = c.TableId
Fist off I know that the join conditions as seen with table A and B are the normal and how I'd rewrite this but I'm wondering if Table C is treated as a LEFT JOIN as it is listed after the LEFT JOIN or if it is treated as an INNER JOIN? My gut says it is treated as an INNER JOIN, but I'm not certain. Which is it?
Furthermore, I know I'm not the only one who has ever seen something like this and it would be good to have this answer immortalized in the StackExchange...
Thanks.
It is effectively an INNER JOIN or CROSS JOIN; the comma has lower precedence than the explicit JOIN, so FROM ... LEFT JOIN ... ON ..., ... means FROM (... LEFT JOIN ... ON ...), ..., with the LEFT JOIN pertaining only to the first two tables.

Resources