MySQL merge 2 tables with same Id values - mysql

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.

Related

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

naural join is giving Cartesian product of two relations

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

MySql - Combine data from three tables into one table

I have 3 tables for data of divisions, districts and police_stations table. The table data are dependent like
divisions
- districts
-- police_stations
Table format are
divisions
id
name
districts
id
division_id
name
police_stations
id
division_id
district_id
name
Can I design just one table with all of my tables data with current table dependency? If I can, how will be the traversing process?
To group multiple tables together, you should use JOINS. This is a better database practice than creating new tables.
The INNER JOIN keyword selects all rows from both tables as long as there is a match between the columns in both tables.
SELECT *
FROM divisions divis
INNER JOIN districts dis
ON dis.division_id = divis.id
INNER JOIN police_stations pol
ON pol.district_id = dis.id
Note: Apparently the DIV keyword is reserved in mysql, so you you have to use something else to identify divisions.
If you insist on creating a new table with this data, you can use the CREATE TABLE AS recipe.
In order to do this though, we need to modify our original schema. New tables cannot have duplicate names, so we have to change the original tables to all have unique columns.
For example name becomes district_name.
CREATE TABLE combined AS (
SELECT divis.id, divis.division_name, dis.district_name, pol.police_name
FROM divisions divis
LEFT JOIN districts dis
ON divis.id = dis.division_id
LEFT JOIN police_stations pol
ON pol.district_id = dis.id
);
Here is a fiddle to demonstrate it
http://sqlfiddle.com/#!9/7ec3b/1/0
This is really bad database design though. My first solution is recommended
Using a single table: There would be an id for uniquely identifying each row; it would be the PRIMARY KEY. There would be a parent_id to say which other row is its 'parent' (division is parent of district, etc).
The JOIN becomes a self join.
SELECT ...
FROM tbl AS division
JOIN tbl AS district ON division.id = district.parent_id
JOIN tbl AS station ON district.id = station.parent_id
WHERE ...
Be sure to 'qualify' each field in the SELECT and WHERE with the appropriate 'alias'; example: division.name.
This design pattern works for most 'hierarchical' structures of arbitrary depth. Yours is exactly 3 levels deep, so it is somewhat simpler.
Note that the parent_id would be 0 for any "district" rows. And it would be useful to have INDEX(parent_id).
Hopefully it solves your problem
SELECT * from divisions d
join police_stations ps on d.id=ps.division_id
join districts dist on ps.district_id =dist.id;

create a new table from a full join

I want to create a new table that includes certain columns from two existing tables. Some columns are in both existing tables, but not all. The column "unique_number" is in both tables. What I want is to check if the same unique_number exists in both tables, and if so then make a single row with all of the columns (from both tables) that correspond to that unique_number. If the unique_number is not in both existing tables then I don't care about including that in my new table.
I can do this in SAS, but I am being forced to do this in SQL with little background knowledge of the program.
It sounds that you need an INNER JOIN instead of a FULL JOIN. This is a way of doing what you want:
SELECT A.unique_number,
A.col1FromA, -- list the other columns from TableA here
B.col1FromB -- list the other columns from TableB here
INTO TableC
FROM TableA A
INNER JOIN TableB B
ON A.unique_number = B.unique_number
An inner join on the "unique_number" column should be all you need, if your description is accurate.
select t1.unique_number, t1.other_column, t2.something_else
into new_table_name
from one_table t1
inner join other_table t2
on t1.unique_number = t2.unique_number;
This glosses over the complication that "some columns are in both tables", and that those columns that are in both tables might have different values. Give some thought to that.
Select...into syntax

MySQL Join with many (fields) to one (secondary table) relationship

I have a query I need to perform on a table that is roughly 1M records. I am trying to reduce the churn, but unfortunately there is a UNION involved (after i figure this join out), so that may be a question for another day.
The records and data I need to get reference 3 fields in a table that need each pull a description from another table and return it in the same record, but when i do the Inner join i was thinking, it either returns only 1 field fromt he other table, or multiple records from he original table.
Here are some screen shots of the tables and their relationship:
Primary table containing records (1 each) with the physician record I want to pull, including up to 3 codes that can be listed in the "taxonomy" table.
Secondary table containing records (1 each) with the "Practice" field I want to pull.
A Quick glance of the relationship i'm talking about
I presume that if perform an inner join matching the 3 fields in the physicians table, that it will have to iterate that table multiple times to pull each taxonomy code .. but I still can't even figure the syntax to easily pull all of these codes instead of just 1 of them.
i've tried this:
SELECT
taxonomy_codes.specialization,
physicians.provider_last_name,
physicians.provider_first_name,
physicians.provider_dba_name,
physicians.legal_biz_name,
physicians.biz_practice_city
FROM
taxonomy_codes
INNER JOIN physicians ON physicians.provider_taxonomy_code_1 = taxonomy_codes.taxonomy_codes OR physicians.provider_taxonomy_code_2 = taxonomy_codes.taxonomy_codes OR physicians.provider_taxonomy_code_3 = taxonomy_codes.taxonomy_codes
First, the query churns a lot and it only returns one taxonomy specialty result which I presume is because of the OR in the join statement. Any help would be greatly appreciated.
Thank you,
Silver Tiger
You have to join the taxonomy_codes table multiple times:
SELECT p.provider_last_name, p...., t1.specialization as specialization1, t2.specialization as specialization2, t3.specialization as specialization3
FROM physicians p
LEFT JOIN taxonomy_codes t1 ON t1.taxonomy_codes = provider_taxonomy_code_1
LEFT JOIN taxonomy_codes t2 ON t2.taxonomy_codes = provider_taxonomy_code_2
LEFT JOIN taxonomy_codes t3 ON t3.taxonomy_codes = provider_taxonomy_code_3