JOIN or not in SQL statement - sql

Suppose I have a SELECT statement, and I use table name such as :
select cust.name from cust,order where cust.id = order.id ;
I didn't use a JOIN statement,
Question is the given statement is JOIN or not?

Yes it is a join statement.When you want to perform a join you have to select all required tables.
When you select all required tables in From and use join , in WHERE it becomes implicit join as below.
select
cust.name
from customer c, [order] o
where c.id = o.id ;
When you use join two tables with JOIN syntax then it is called explicit join as below
select
cust.name
from customer c
join [order] o
on c.id = o.id ;

You seem to be trying to write a join query using the implicit join syntax. That should look something like this:
select cust.name from cust, order where cust.id = order.id;
But actually, order is a reserved keyword in just about every version of SQL, so you should escape it, maybe using double quotes:
select cust.name from cust, "order" where cust.id = "order".id;
However, it is much preferable to use modern, explicit join syntax now, so please use:
select cust.name from cust inner join "order" on cust.id = "order".id;
And consider renaming your order table to something other than a reserved keyword.

The , is an archaic way of writing JOINs in SQL. It basically means CROSS JOIN, although the semantics are slightly different in the FROM clause.
It was replaced in the 1990's -- yes, the last millennium -- by proper, explicit, standard, readable JOIN syntax. As much as I dislike commas, they are part of the SQL language. I do wish they would be deprecated, but that has not yet occurred (that would mean that newer databases would have no obligation to support the syntax).
I think you know that you should be using:
select c.name
from cust c join
order o
on c.id = o.id ;
(An aside, order is a really bad name for a table because it is an Oracle keyword.)
The word "join" can mean multiple things when talking about databases.
It can mean the JOIN operator, which is a specific operator in the FROM clause.
It can mean the "join" operation in the FROM clause. By this definition, , is a "join" operation, which is equivalent to CROSS JOIN.
It can mean the combining of data from any multiple tables -- basically using underlying "join" algorithms. By this definition, IN, EXISTS, and so on might be "join" operations, even though they are not in the FROM clause.

Related

join without a join in PostgresSQL

I have code with the following psql query that I try to understand (It was simplified for the question):
select id, time, t.type, t.sub_type from TABLE_A r,TABLE_B t,TABLE_C l where r.type = t.type and t.type = l.type
Is it the same as doing a join, or am I missing something here?
You are doing an old school implicit join. This is the syntax used before the ANSI-92 SQL standard which started recommending explicit joins like this version of your query:
select id, time, t.type, t.sub_type -- but please always use aliases here
from TABLE_A r
inner join TABLE_B t
on r.type = t.type
inner join TABLE_C l
on t.type = l.type;
The above version is considered the "correct" way of expressing your logic. Explicit joins solved a number of problems inherent with implicit joins. Implicit joins place both the join logic and the filter criteria into the same WHERE clause, potentially making it difficult to tease apart what is happening there. In addition, it was harder to express left/right/inner/cross join using the implicit syntax, with different vendors sometimes having different syntax. The ANSI-92 explicit join is pretty much the same across all the major SQL vendors at this point.

When to cross or join two tables?

Example 1:
SELECT name
FROM Customer, Order
WHERE Customer.id = Order.cid
Example 2:
SELECT name
FROM Customer JOIN Order
ON Customer.id = Order.cid
What is the difference between these two queries? When should I cross two tables vs JOIN?
Both will give you identical result. So there is no real situation to use one over another.
The comma separated join, is an ANSI 89 standard join, INNER JOIN is the newer ANSI 92 standard join.
However comma separated join syntax is depreciated we always prefer to use INNER JOIN syntax. When you want to join more than one table it will be difficult to follow the join conditions in Where clause where as INNER JOIN syntax is more readable
CROSS JOIN operation is a Cartesian product. Result of CROSS JOIN operation
between set A and set B is the superset that contains all values.
Then with operator WHERE you are filtering this result set.
INNER JOIN operation will try to find rows from both tables that correspond predicate
after keyword ON. That rows will go to the result set.
Practically, SQL engine can choose its own physical implementation CROSS JOIN operator.
SQL engine doesn't have to get huge result set and then filter it. SQL engine behaviour will
be similar when using INNER JOIN operation.

Cannot run a natural join

I have two tables:
A table takes with attributes ID and Course_ID
A table course with attributes Course_ID, title, and dept_name
I want to retrieve title and dept_name using a natural join on the two tables, but it returns an error:
incorrect syntax near ';'
My code:
select title, dept_name
from takes
natural join course;
What is wrong with my code?
PS. My textbook does not mention using the on keyword. Besides that, it also mentions to use the operator using to specify the common attributes, but this doesn't help either.
Well standard SQL supports a concept called natural join, which represents an inner
join based on a match between columns with the same name in both sides. For example,
T1 NATURAL JOIN T2 joins the rows between T1 and T2 based on a match between the
columns with the same names in both sides.
T-SQL being a dialect of SQL, doesn’t have an implementation of a natural join, as of SQL Server 2012.
So in your case as takes and course has a common column Course_ID , equivalent representation in T-SQL will be:
select C.title, C.dept_name
from takes T
INNER JOIN course C on C.Course_ID = T.Course_ID;
Sqlserver does not support natural join. Instead of that you can use
INNER JOIN
select c.title, c.dept_name
from takes t
inner join course c on t.Course_ID = c.Course_ID;
Besides that, it also mentions to use the operator using to specify the common attributes, but this doesn't help either.
You either mis-read the textbook or that textbook is plain wrong. natural join does not require any specification on which column to use.
The USING attribute is used for a "regular" join:
select c.title, c.dept_name
from takes t
join course c using (Course_ID);
join is equivalent to inner join. The keyword inner is optional.
join course using (Course_ID) is equivalent to join course c on t.course_id = c.course_id

Queries that implicit SQL joins can't do?

I've never learned how joins work but just using select and the where clause has been sufficient for all the queries I've done. Are there cases where I can't get the right results using the WHERE clause and I have to use a JOIN? If so, could someone please provide examples? Thanks.
Implicit joins are more than 20 years out-of-date. Why would you even consider writing code with them?
Yes, they can create problems that explicit joins don't have. Speaking about SQL Server, the left and right join implicit syntaxes are not guaranteed to return the correct results. Sometimes, they return a cross join instead of an outer join. This is a bad thing. This was true even back to SQL Server 2000 at least, and they are being phased out, so using them is an all around poor practice.
The other problem with implicit joins is that it is easy to accidentally do a cross join by forgetting one of the where conditions, especially when you are joining too many tables. By using explicit joins, you will get a syntax error if you forget to put in a join condition and a cross join must be explicitly specified as such. Again, this results in queries that return incorrect values or are fixed by using distinct to get rid of the cross join which is inefficient at best.
Moreover, if you have a cross join, the maintenance developer who comes along in a year to make a change doesn't know if it was intended or not when you use implicit joins.
I believe some ORMs also now require explicit joins.
Further, if you are using implied joins because you don't understand how joins operate, chances are high that you are writing code that, in fact, does not return the correct result because you don't know how to evaluate what the correct result would be since you don't understand what a join is meant to do.
If you write SQL code of any flavor, there is no excuse for not thoroughly understanding joins.
Yes. When doing outer joins. You can read this simple article on joins. Joins are not hard to understand at all so you should start learning (and using them where appropriate) right away.
Are there cases where I can't get the right results using the WHERE clause and I have to use a JOIN?
Any time your query involves two or more tables, a join is being used. This link is great for showing the differences in joins with pictures as well as sample result sets.
If the join criteria is in the WHERE clause, then the ANSI-89 JOIN syntax is being used. The reason for the newer JOIN syntax in the ANSI-92 format, is that it made LEFT JOIN more consistent across various databases. For example, Oracle used (+) on the side that was optional while in SQL Server you had to use =*.
Implicit join syntax by default uses Inner joins. It is sometimes possible to modify the implicit join syntax to specify outer joins, but it is vendor dependent in my experience (i know oracle has the (-) and (+) notation, and I believe sqlserver uses *= ). So, I believe your question can be boiled down to understanding the differences between inner and outer joins.
We can look at a simple example for an inner vs outer join using a simple query..........
The implicit INNER join:
select a.*, b.*
from table a, table b
where a.id = b.id;
The above query will bring back ONLY rows where the 'a' row has a matching row in 'b' for it's 'id' field.
The explicit OUTER JOIN:
select * from
table a LEFT OUTER JOIN table b
on a.id = b.id;
The above query will bring back EVERY row in a, whether or not it has a matching row in 'b'. If no match exists for 'b', the 'b' fields will be null.
In this case, if you wanted to bring back EVERY row in 'a' regardless of whether it had a corresponding 'b' row, you would need to use the outer join.
Like I said, depending on your database vendor, you may still be able to use the implicit join syntax and specify an outer join type. However, this ties you to that vendor. Also, any developers not familiar wit that specialized syntax may have difficulty understanding your query.
Any time you want to combine the results of two tables you'll need to join them. Take for example:
Users table:
ID
FirstName
LastName
UserName
Password
and Addresses table:
ID
UserID
AddressType (residential, business, shipping, billing, etc)
Line1
Line2
City
State
Zip
where a single user could have his home AND his business address listed (or a shipping AND a billing address), or no address at all. Using a simple WHERE clause won't fetch a user with no addresses because the addresses are in a different table. In order to fetch a user's addresses now, you'll need to do a join as:
SELECT *
FROM Users
LEFT OUTER JOIN Addresses
ON Users.ID = Addresses.UserID
WHERE Users.UserName = "foo"
See http://www.w3schools.com/Sql/sql_join.asp for a little more in depth definition of the different joins and how they work.
Using Joins :
SELECT a.MainID, b.SubValue AS SubValue1, b.SubDesc AS SubDesc1, c.SubValue AS SubValue2, c.SubDesc AS SubDesc2
FROM MainTable AS a
LEFT JOIN SubValues AS b ON a.MainID = b.MainID AND b.SubTypeID = 1
LEFT JOIN SubValues AS c ON a.MainID = c.MainID AND b.SubTypeID = 2
Off-hand, I can't see a way of getting the same results as that by using a simple WHERE clause to join the tables.
Also, the syntax commonly used in WHERE clauses to do left and right joins (*= and =*) is being phased out,
Oracle supports LEFT JOIN and RIGHT JOIN using their special join operator (+) (and SQL Server used to support *= and =* on join predicates, but no longer does). But a simple FULL JOIN can't be done with implicit joins alone:
SELECT f.title, a.first_name, a.last_name
FROM film f
FULL JOIN film_actor fa ON f.film_id = fa.film_id
FULL JOIN actor a ON fa.actor_id = a.actor_id
This produces all films and their actors including all the films without actor, as well as the actors without films. To emulate this with implicit joins only, you'd need unions.
-- Inner join part
SELECT f.title, a.first_name, a.last_name
FROM film f, film_actor fa, actor a
WHERE f.film_id = fa.film_id
AND fa.actor_id = a.actor_id
-- Left join part
UNION ALL
SELECT f.title, null, null
FROM film f
WHERE NOT EXISTS (
SELECT 1
FROM film_actor fa
WHERE fa.film_id = f.film_id
)
-- Right join part
UNION ALL
SELECT null, a.first_name, a.last_name
FROM actor a
WHERE NOT EXISTS (
SELECT 1
FROM film_actor fa
WHERE fa.actor_id = a.actor_id
)
This will quickly become very inefficient both syntactically as well as from a performance perspective.

SQL JOIN: ON vs Equals

Is there any significant difference between the following?
SELECT a.name, b.name FROM a, b WHERE a.id = b.id AND a.id = 1
AND
SELECT a.name, b.name FROM a INNER JOIN b ON a.id = b.id WHERE a.id = 1
Do SO users have a preference of one over the other?
There is no difference, but the readability of the second is much better when you have a big multi-join query with extra where clauses for filtering.
Separating the join clauses and the filter clauses is a Good Thing :)
The former is ANSI 89 syntax, the latter is ANSI 92.
For that specific query there is no difference. However, with the former you lose the ability to separate a filter from a join condition in complex queries, and the syntax to specify LEFT vs RIGHT vs INNER is often confusing, especially if you have to go back and forth between different db vendors. There are also certain kinds of join that cannot be written with the old syntax.
In fact, the former syntax has been obsolete for more than 30 years now, and should not be used for new development.
There is no difference to the sql query engine.
For readability, the latter is much easier to read if you use linebreaks and indentation.
For INNER JOINs, it does not matter if you put "filters" and "joins" in ON or WHERE clause, the query optimizer should decide what to do first anyway (it may chose to do a filter first, a join later, or vice versa
For OUTER JOINs however, there is a difference, and sometimes youll want to put the condition in the ON clause, sometimes in the WHERE. Putting a condition in the WHERE clause for an OUTER JOIN can turn it into an INNER JOIN (because of how NULLs work)
For example, check the readability between the two following samples:
SELECT c.customer_no, o.order_no, a.article_no, r.price
FROM customer c, order o, orderrow r, article a
WHERE o.customer_id = c.customer_id
AND r.order_id = o.order_id
AND a.article_id = r.article_id
AND o.orderdate >= '2003-01-01'
AND o.orderdate < '2004-01-01'
AND c.customer_name LIKE 'A%'
ORDER BY r.price DESC
vs
SELECT c.customer_no, o.order_no, a.article_no, r.price
FROM customer c
INNER JOIN order o
ON o.customer_id = c.customer_id
AND o.orderdate >= '2003-01-01'
AND o.orderdate < '2004-01-01'
INNER JOIN orderrow r
ON r.order_id = o.order_id
INNER JOIN article a
ON a.article_id = r.article_id
WHERE c.customer_name LIKE 'A%'
ORDER BY r.price DESC
Whilst you can perform most tasks using both and in your case there is no difference whatsoever, I will always use the second at all times.
It's the current supported standard
It keeps joins in the FROM clause and filters in the WHERE clause
It makes more complex LEFT, RIGHT, FULL OUTER joins much easier
MSSQL Help is all based around that syntax therefore much easier to get help on your problem queries
While there is no difference technically, you need to be extra careful about doing joins using the first method. If you get it wrong by accident, you could end up doing a cartesian join between your a and b tables (a very long, memory & cpu intensive query - it will match each single row in a with all rows in b. Bad if a and b are large tables to begin with). Using an explicit INNER JOIN is both safer and easier to read.
No difference. I find the first format more readable and use the second format only when doing other types of joins (OUTER, LEFT INNER, etc).
The second form is SQL92 compliant syntax. This should mean that it is supported by all current and future databases vendors. However , the truth is that the first form is so pervasive that it is also guaranteed to be around for longer than we care.
Otherwise they are same in all respects in how databases treat the two.