Cartesian product and Join in logical query tree - mysql

im currently working on logical query tree, can someone explain me what is difference between cartesian product and join in logical tree.
I know that JOIN combines the two or more records but displays only matching values, but i dont understand when i should use Join and when Cartesian product.

Related

Relational Algebra - how does natural join work?

A natural join is an inner join that only works if table1 has some intersecting attributes with table2.
Yet, when I take tables that have no column names in common, it acts as a Cartesian product.
In addition, when I take different tables that have nothing in common, it displays no results.
Why?
Well, you have learned the first important lesson, which is to avoid natural join. It is just lousy syntax, because it does not even take properly declared foreign key relationships into account and the join conditions are hidden -- which makes queries hard to maintain and debug.
A natural join is an inner join equijoin with the join conditions on columns with the same names. Natural joins do not even take types into account, so the query can have type conversion errors if your data is really messed.
If the corresponding inner join on the common column names have no matches, then it returns the empty set. If there are no common column names, then it is the same as a cross join.
The way to think about it is that a natural join (inner natural join) generates the Cartesian product of two tables. When the tables have duplicated column names, then the final result set contains only those Cartesian-product rows where the common column names have the same value.

Difference between CROSS JOIN and INNER JOIN, LEFT JOIN, RIGHT JOIN, OUTER JOIN [duplicate]

This question already has answers here:
MySQL: Quick breakdown of the types of joins [duplicate]
(3 answers)
Closed 3 years ago.
As I understand it, CROSS JOIN is essentially a cross product which produces a Cartesian Product. Are INNER JOIN, RIGHT JOIN, LEFT JOIN, OUTER JOIN Cartesian products as well except for fact that they don't produce duplicates and have some condition applied to them?
Thanks!
Note: I don't believe this is a duplicate. The link does not elaborate on the difference to the detail that I was looking for. It's left up to the reader to dig through & infer the differences. The answer I've provided below will hopefully save the reader some time.
The JOIN operation can be specified as a CARTESIAN PRODUCT operation
followed by a SELECT operation.
...
The result of the JOIN is a relation Q with n + m attributes Q(A1, A2,
... , An, B1, B2, ... , Bm) in that order; Q has one tuple for each
combination of tuples—one from R and one from S—whenever the
combination satisfies the join condition. This is the main difference
between CARTESIAN PRODUCT and JOIN. In JOIN, only combinations of
tuples satisfying the join condition appear in the result, whereas in
the CARTESIAN PRODUCT all combinations of tuples are included in the
result. The join condition is specified on attributes from the two
relations R and S and is evaluated for each combination of tuples.
Each tuple combination for which the join condition evaluates to TRUE
is included in the resulting relation Q as a single combined tuple.
Source: Fundamentals of Database Systems (7th edition), Elmasri

MySQL SELECT from two tables with COUNT

i have two tables as below:
Table 1 "customer" with fields "Cust_id", "first_name", "last_name" (10 customers)
Table 2 "cust_order" with fields "order_id", "cust_id", (26 orders)
I need to display "Cust_id" "first_name" "last_name" "order_id"
to where i need count of order_id group by cust_id like list total number of orders placed by each customer.
I am running below query, however, it is counting all the 26 orders and applying that 26 orders to each of the customer.
SELECT COUNT(order_id), cus.cust_id, cus.first_name, cus.last_name
FROM cust_order, customer cus
GROUP BY cust_id;
Could you please suggest/advice what is wrong in the query?
You issue here is that you have told the database how these two tables are 'connected', or what they should be connected by:
Have a look at this image:
~IMAGE SOURCE
This effectively allows you to 'join' two tables together, and use a query between them.
so you might want to use something like:
SELECT COUNT(B.order_id), A.cust_id, A.first_name, A.last_name
FROM customer A
LEFT JOIN cust_order B //this is using a left join, but an inner may be appropriate also
ON (A.cust_id= B.Cust_id) //what links them together
GROUP BY A.cust_id; // the group by clause
As per your comment requesting some further info:
Left Join (right joins are almost identical, only the other way around):
The SQL LEFT JOIN returns all rows from the left table, even if there are no matches in the right table. This means that if the ON clause matches 0 (zero) records in right table, the join will still return a row in the result, but with NULL in each column from right table. ~Tutorials Point.
This means that a left join returns all the values from the left table, plus matched values from the right table or NULL in case of no matching join predicate.
LEFT joins will be used in the cases where you wish to retrieve all the data from the table in the left hand side, and only data from the right that match.
Execution Time
While the accepted answer in this case may work well in small datasets, it may however become 'heavy' in larger databases. This is because it was not actually designed for this type of operation.
This was the purpose of Joins to be introduced.
Much work in database-systems has aimed at efficient implementation of joins, because relational systems commonly call for joins, yet face difficulties in optimising their efficient execution. The problem arises because inner joins operate both commutatively and associatively. ~Wikipedia
In practice, this means that the user merely supplies the list of tables for joining and the join conditions to use, and the database system has the task of determining the most efficient way to perform the operation. A query optimizer determines how to execute a query containing joins. So, by allowing the dbms to choose the way your data is queried, you can save a lot of time.
Other Joins/Summary
AN INNER JOIN will return data from both tables where the keys in each table match
A LEFT JOIN or RIGHT JOIN will return all the rows from one table and matching data from the other table.
Use a join when you want to query multiple tables.
Joins are much faster than other ways of querying >=2 tables (speed can be seen much better on larger datasets).
You could try this one:
SELECT COUNT(cus_order.order_id), cus.cust_id, cus.first_name, cus.last_name
FROM cust_order cus_order, customer cus
WHERE cus_order.cust_id = cus.cust_id
GROUP BY cust_id;
Maybe an left join will help you
SELECT COUNT(order_id), cus.cust_id, cus.first_name, cus.last_name ]
FROM customer cus
LEFT JOIN cust_order co
ON (co.cust_id= cus.Cust_id )
GROUP BY cus.cust_id;

Slow Mysql Query with 3 left join

We have a e-store and in this e-store there is many complicated links between categories and products.
I'm using Taxonomy table in order to store relations between Products-Categories and Products-Products as sub product.
Products may be member of more than one category.
Products may be a sub product a sub product of an other product. (May be more than one)
Products may be a module of an other product (May be more than one)
aliases of query :
pr-Product
ct-Category
sp-Sub Product
md-Module
Select pr.*,ifnull(sp.destination_id,0) as `top_id`,
ifnull(ct.destination_id,0) as `category_id`
from Products as pr
Left join Taxonomy as ct
on (ct.source_id=pr.id and ct.source='Products' and ct.destination='Categories')
Left join Taxonomy as sp
on (sp.source_id=pr.id and sp.source='Products' and sp.destination='Products' and sp.type='TOPID')
Left join Modules as md
on(pr.id = md.product_id)
where pr.deleted=false
and ct.destination_id='47'
and sp.destination_id is null
and md.product_id is null
order by pr.order,pr.sub_order
With this query; I'm trying to get all products under Category_id=47 and not module of any product and not sub product of any product.
This query takes 23 seconds.
There is 7.820 Records in Products, 3.200 Records in Modules and 19.000 records in Taxonomy
I was going to say that MySQL can only use one index per query but it looks like that is no longer the case. I also came across this in another answer:
http://dev.mysql.com/doc/mysql/en/index-merge-optimization.html
However that may not help you.
In the past, when I've come across queries MySQL couldn't optimised I've settled for precomputing answers in another table using a background job.
What you're trying to do looks like a good fit for a graph database like neo4j.
MySQL's optimizer is known to be bad in changing Outer to Inner joins automatically, it does the outer join first and then starts to filter data.
In your case the join between Products and Taxonomy can be rewritten as an Inner Join (there's a WHERE-condition on ct.destination_id='47').
Try if this changes the execution plan and improves performance.

Natural join if no common attributes

What will natural join return in relational algebra if tables don't have attributes with same names? Will it be null or the same as cross join (cross product) (Cartesian product)?
If there are no attributes in common between two relations and you perform a natural join, it will return the cartesian product of the two relations.
The cartesian product of the two tables will be returned. This is because, when we perform any JOIN operation on two tables, a cartesian product of those tables is formed. Then, based on any select condition in the WHERE clause, the resultant rows are returned. But here, as there are no common columns, the process stops after finding the cartesian product.
It will return the cartesian product of the tables. If there are any common attributes, then the natural join removes the duplicate attributes.