naural join is giving Cartesian product of two relations - mysql

I have two relations, emp(id,name) and emp2(name,city,salary) with values:
and relation emp2 values :
As you can see, when I run natural join between them I get their Cartesian product.
But why, since they have a common attribute (name)?

You are getting natural join, not Cartesian product.
There is one copy of each common column and one copy of each column unique to an input table. There is a row for every different combination of a row from the left input table and a row from a right input table.
If a subrow value (('kim')) for common columns (name) appears n times in the left table (2 times) and m times in the right table (2 times) then it will appear n times m times in the output (2 times 2 times = 4 times).
An SQL Cartesian product would have columns name, city, salary, id & name and would have a row for every different combination of a row from the left input table and a row from a right input table.
That includes every possible combination of a name value from the left table and the right table. But for this example data there is only one name value over both tables, so every pair of name values has to have that value twice.
Natural join is the same as Cartesian product followed by restriction on equality of common columns followed by projecting away one of each common column followed by keeping distinct rows.

select * from emp inner join emp2 on emp.id = emp2.id

You have two time the same value in the common column (name) so this retrive the rows more time .
Your natural join is based on both the table that have not unique value each row.
Then in this case you get always more that a row for each entry (also with inner join) but you could solve using distinct
select dictinct emp.*, emp2.*
from emp
inner join emp2 on emp.name = emp2.name
or
select select dictinct emp.*, emp2.*
from emp2 natural join emp

Related

Combine 3 tables with sum mysql

I have a problem with my query. I've managed to display data from 2 tables. Next I want to add up SALE_AMT from the 3rd table, the problem is that order by cannot, the program output adds up all data not by order by
This my query:
SELECT
customer.CUST_NO, customer.CUST_NM,
store.STR_CD, store.STR_NM, SUM(SALE_AMT)
FROM
customer, store, cust_sale_pnt
GROUP BY
CUST_NO
table customer
table cust_sale_pnt
table store
My result
my result
Can you guys help me to sum data based on grouping cust_no?
The problem is, that you don't specify a condition that's used to combine the records of the different tables. In effect, you're creating a 'cross join'.
That is, any record of table customer is combined with any record of table store and the result is combined with any record of table cust_sale_pnt.
In effect, you get each of your 3 customers combined with each of your 6 sales. Therefore the sum over sale_amt is identical for each customer.
You want an INNER JOIN to combine the records:
SELECT c.CUST_NO, c.CUST_NM, SUM(csp.SALE_AMT)
FROM customer c
INNER JOIN cust_sale_pnt csp ON c.CUST_NO = csp.CUST_NO
INNER JOIN store ON csp.STR_CD = store.STR_CD
GROUP BY c.CUST_NO, c.CUST_NM;

Create table from joined table in MySQL

I have no problem joining the tables, but when I go to create a new table using the joined tables, I get an error saying that I have duplicate columns.
My code:
SELECT *
FROM field
INNER JOIN race
ON field.raceID = race.raceID;
Updated code:
CREATE TABLE fieldrace AS
SELECT f.*, r.*
FROM field f
INNER JOIN race r
ON f.raceID = r.raceID;
That's true of any select. If there are duplicated column names, you have to reference them somehow. For a .* query this would work:
SELECT f.*, r.*
FROM field f
INNER JOIN race r
ON f.raceID = r.raceID;
Individually you can also add aliases. Maybe you have an id column in both race and field tables.
SELECT f.id as field_id, r.id as race_id, ....
FROM field f
INNER JOIN race r
ON f.raceID = r.raceID;
In the query
CREATE TABLE fieldrace AS
SELECT f.*, r.*
FROM field f
INNER JOIN race r
ON f.raceID = r.raceID;
SELECT part produces two columns with the same name in the output.
Two columns with the same name presence is not allowed in table's structure, and the whole query will fail.
General solution is to list each output column in the SELECT part separately with assigning them unique aliases.
If raceID column which is used for joining is the only column whose name interferes then you may use either USING clause instead of ON clause or NATURAL JOIN instead of INNER JOIN.
CREATE TABLE fieldrace AS
SELECT f.*, r.*
FROM field f
INNER JOIN race r USING (raceID);
-- or
CREATE TABLE fieldrace AS
SELECT f.*, r.*
FROM field f
NATURAL INNER JOIN race r;
In both cases the interfered columns will be collapsed into one column which will be placed to the top of created table structure.
Of course when raceID is not the only column whose name interferes then 1st of these queries will fail due to another column duplication whereas 2nd query will use all interfered columns for joining.
You may specify complete or partial structure of newly create table. In this case the amount and relative posession of the columns in the created table won't be changed (will match SELECT output) but all another properties of the columns (datatype, nullability, etc.) and additional objects (indices, constraints, etc.) listed in the structure will be applied. The columns which are absent in the output (including generated ones) will be added into the structure with default values as the most first ones, before the columns used in USING or during NATURAL JOIN even. DEMO.
you can create "view" or name a subquery using "with"
in both cases, you can access it from anywhere in your main query

Join more than two tables

I am trying to join 2 tables and in 1 table there may or may not have the corresponding values.but i need to join the table and list the fields as null.
I have tried to join the tables as left join.but If two entries is there in secoond table corresponding to the value of first table,then first table data is displayed twice.
I need to display only one time if there is two data in another table or there is no data in another table,but it should display as null.
Here is my sql query.
SELECT *,incident.incident_id as incidentid
FROM register_incident AS incident
LEFT JOIN incident_images AS im ON im.incident_id=
incident.incident_id
WHERE incident.state='Active'
I need to display only one time each data if there is no corresponding rows in another table,but the fields in the second table list as null.
If there is more than one row in another table,then also display each row in first table one time with one entry in the second table.
you can use select distinct for get only one row eg (limiting the select to indicent_id ,, but you can add the distinctcolumn you need ):
SELECT *,incident.incident_id as incidentid
FROM register_incident AS incident
LEFT JOIN (
select distinct incident_id from
incident_images
WHERE incident.state='Active' ) t ON t.incident_id= incident.incident_id

Finding Non Matching ID

I have two tables, called "One" and "Two", they are both the same, table "One" has some IDs that are not there in Table "Two". but when i run this mysql Query, i can not get those non-matching values.
select count(bene) from one where bene not in (select bene from two);
And the result is Zero. so how do i get the non-matching values from Table one that are not there in table Two?
You can perform a left join and find only values that do not exist in second table. Below query is assuming that bene is your ID column:
SELECT one.*
FROM one
LEFT JOIN two ON one.bene = two.bene
WHERE two.bene IS NULL
or if you need just the count
SELECT COUNT(one.bene)
FROM one
LEFT JOIN two ON one.bene = two.bene
WHERE two.bene IS NULL
When performing a Left join you find all values in table one with corresponding values in table two. If there is no match all table two values will be NULL.
Then as a second step you use WHERE to filter only rows that have NULL for table two. This way you find all records in table one that do not have matching records in table two.
select count(*) from one a where not exists (select * from two b where a.bene=b.bene)

MySQL merge 2 tables with same Id values

I have a MySQL db that has 2 tables that have related information that I need to merge to 1 table.
Gallery has an itemid that relates to rbitems Id. Both tables gallery and rbitems have different column names but both have unique data. I want to merge the two tables based on the Id and itemid columns.
So how do I merge 2 different tables into 1 based on 1 column having unique values. I'd like to just append the other tables to the merge.
You can use JOIN to solve your problem.
SELECT a.*, b.*
FROM galley a INNER JOIN rbitems b
on a.itemid = b.id
CREATE TABLE new_table
AS (SELECT g.itemid, g.a, g.b, g.c, r.x, r.y, r.z
FROM gallery g INNER JOIN rbitems r
ON g.itemid = r.id
);
You may wish to add "AS name" to the members of the select clause.
If you have elements of the original tables that are not represented in the other table you should look into RIGHT, LEFT, or OUTER JOIN instead of INNER.
This assumes that the itemid and id columns are unique--a given itemid/id does not exist multiple times in the same table.