Can I add a new auto-increment column to this UNION? - mysql

I’m trying to join two tables getting all the data from both tables.
I managed to UNION both tables, but I need to add an ID with auto-increment as the primary key for the new table that I’m creating.
I don't know how to do it and can’t find a way to add it to the query.
CREATE TABLE NEWTABLE
SELECT T1.TEXT as TEXT
[...]
FROM TABLE1 T1
LEFT JOIN TABLE2 T2
on T1.TEXT = T2.TEXT
UNION
SELECT T2.TEXT as TEXT
FROM TABLE1 T1
[...]
RIGHT JOIN TABLE2 T2
on T1.TEXT = T2.TEXT

You need to put the column definitions in the CREATE TABLE statement to add the id column. Then provide NULL as the values for it in the SELECT queries.
CREATE TABLE NEWTABLE (
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
text TEXT,
[...]
) AS
SELECT null, T1.TEXT
[...]
FROM TABLE1 T1
LEFT JOIN TABLE2 T2
on T1.TEXT = T2.TEXT
UNION
SELECT null, T2.TEXT as TEXT
FROM TABLE1 T1
[...]
RIGHT JOIN TABLE2 T2
on T1.TEXT = T2.TEXT

Related

INNER JOIN creates duplicate primary key error but it shouldn't

I'm trying to make a new table from the inner join results of three other tables (t1, t2, t3)
INSERT INTO new_table
SELECT
t1.application_id,
t1.text,
t2.names,
t2.title,
t3.org_name, t3.project_start, t3.project_end, t3.keywords
FROM t1
INNER JOIN t2 ON t1.application_id = t2.application_id
INNER JOIN t3 ON t1.application_id = t3.application_id;
but keep getting a ER_DUP_ENTRY: Duplicate entry '9481301' for key 'PRIMARY'error. Each table should have id as a primary key so I'm confused why this is happening - how would one find and delete all the duplicates?
I bet your new_table is defined with an AUTOINCREMENT primary key.
To make your INSERT work correctly you'll need to let MySQL set that value rather than providing it from your SELECT. Something like this may work for you.
INSERT INTO new_table
(text, names, title, org_name, project_start, project_end, keywords)
SELECT
t1.text,
t2.names,
t2.title,
t3.org_name, t3.project_start, t3.project_end, t3.keywords
FROM t1
INNER JOIN t2 ON t1.application_id = t2.application_id
INNER JOIN t3 ON t1.application_id = t3.application_id;
You do this by leaving the id value out of your SELECT, and by enumerating the columns you want to INSERT.
(This is a guess: you didn't show us your table definition.)

SQL Select on multiple tables to check if value exists in one table and not used in other

I have 2 tables:
table1 (id,usedcode)
table2 (codeid,uniquecode)
I want to be able to check if a certain value exists in uniquecode of Table2, but is not already used in Table1
Try using left join as below:
SELECT t2.*
FROM table2 t2 LEFT JOIN table1 t1
ON t2.uniquecode = t1.usedcode
WHERE t1.usedcode IS null
SELECT uniquecode FROM Table2
WHERE NOT EXISTS(
SELECT * FROM Table1 WHERE usedcode = uniquecode
)
In English the query is saying, "Select all unique codes from table 2 that don't exist in table 1 as a usedcode".

More efficient query than NOT IN (nested select)

I have two tables table1 and table2 their definitions are:
CREATE `table1` (
'table1_id' int(11) NOT NULL AUTO_INCREMENT,
'table1_name' VARCHAR(256),
PRIMARY KEY ('table1_id')
)
CREATE `table2` (
'table2_id' int(11) NOT NULL AUTO_INCREMENT,
'table1_id' int(11) NOT NULL,
'table1_name' VARCHAR(256),
PRIMARY KEY ('table2_id'),
FOREIGN KEY ('table1_id') REFERENCES 'table1' ('table1_id')
)
I want to know the number of rows in table1 that are NOT referenced in table2, that can be done with:
SELECT COUNT(t1.table1_id) FROM table1 t1
WHERE t1.table1_id NOT IN (SELECT t2.table1_id FROM table2 t2)
Is there a more efficient way of performing this query?
Upgrade to MySQL 5.6, which optimizes semi-joins against subqueries better.
See http://dev.mysql.com/doc/refman/5.6/en/subquery-optimization.html
Or else use an exclusion join:
SELECT COUNT(t1.table1_id) FROM table1 t1
LEFT OUTER JOIN table2 t2 USING (table1_id)
WHERE t2.table1_id IS NULL
Also, make sure table2.table1_id has an index on it.
try using EXISTS.. its generally more efficient than IN
SELECT COUNT(t1.table1_id)
FROM table1 t1
WHERE EXISTS
( SELECT 1
FROM table2 t2
WHERE t2.table1_id <=> t1.table1_id
)
you can do it with NOT EXISTS as well
SELECT COUNT(t1.table1_id)
FROM table1 t1
WHERE NOT EXISTS
( SELECT 1
FROM table2 t2
WHERE t2.table1_id = t1.table1_id
)
EXISTS is generally faster because the execution plan is once it finds a hit, it will quit searching since the condition has proved true. The problem with IN is it will collect all the results from the subquery before further processing... and that takes longer
As #billkarwin noted in the comments EXISTS is using a dependent subquery.. Here is the explain on my two queries and also the OP's query.. http://sqlfiddle.com/#!2/53199d/5

Joining tables with Foreign Keys

How do I INNER JOIN a table that contains 2 foreign keys as its primary keys?
CREATE TABLE table1 (table1ID CHAR(4));
CREATE TABLE MEM_INSTR (table2ID CHAR(4));
CREATE TABLE table3 (table1ID CHAR(4), table2ID CHAR(4));
Assuming you want to just join everything together as keys suggest...
SELECT *
FROM table1
INNER JOIN table3 on table3.table1ID = table1.table1ID
INNER JOIN MEM_INSTR on MEM_INSTR.table2ID = table3.table2ID
But let's say that you have this scenario.
CREATE TABLE Table1 (
Table1ID NUMBER,
Generation NUMBER,
...
);
CREATE TABLE Table2 (
Table2ID NUMBER,
Table1ID NUMBER,
Table1Generation NUMBER,
...
);
Let's say for argument's sake that Table1 can have multiple records with the same Table1ID, and Generation is used as a secondary key. And you need to join a Table2 record to the correct single Table1 record. You can expand the ON clause the same way you would expand a WHERE clause.
SELECT *
FROM table1 t1
INNER JOIN table2 t2
ON t2.table1id = t1.table1id
AND t2.table1generation = t1.generation
You join it like you usually do, nothing really special about that. So you go something like this:
SELECT ...
FROM table1
INNER JOIN table3 ON table3.table1ID = table1.table1ID
INNER JOIN MEM_INSTR ON MEM_INSTR.table2ID = table3.table2ID

Select from MySQL table while ordering by IDs from another table

This might be something very simple to do. If so, I apologize. I'm still learning MySQL.
Say, I have two tables:
Table1:
`id` int autoincrement primary key
`Name` tinytext
`Phone` tinytext
`Date` etc.
and
Table2:
`id` int autoincrement primary key
`itmID` int
Each row in Table2 specifes the order at which elements should be selected out of Table1. itmID field in Table2 is linked to id field in Table1.
So right at this moment to select elements from Table1 I do this:
SELECT * FROM `Table1`;
But how do you order them according to Table2, something like this?
SELECT * FROM `Table1` ORDER BY <itmID's in Table2> ASC;
If all ids of the Table1 have an entry on Table2 use an INNER JOIN, like this.
SELECT * FROM Table1 t1
INNER JOIN Table2 t2 ON t1.id = t2.itmID
ORDER BY t2.itmID
If not all of them have an entry, then use a LEFT JOIN, like this:
SELECT * FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.id = t2.itmID
ORDER BY t2.itmID
Select from the first table, join it to the second, and order by the second. Something like
SELECT *
FROM table1
LEFT JOIN table 2 on table.id = table2.id
ORDER by table2.itmID
Ryan's answer is almost right
SELECT *
FROM table1
INNER JOIN table2 on table1.id = table2.itmID
ORDER BY table2.id
http://dev.mysql.com/doc/refman/5.5/en/join.html
SELECT * FROM `Table1`
INNER JOIN `Table2` USING (`id`)
ORDER BY `Table2`.`itmID` ASC