I need to move data from one table into two tables.
for example
I have TableA with A,B,C,D,E fields (this is the old table), and TableX and TableY. TableX contains A,B and C fields and TableY contains D and E.
Currently I have a query that inserts the data into the first table but not in the second, something like
INSERT INTO TableX
(A,B,C)
SELECT A,B,C
FROM TableA
This works
The 3 tables contains their id's and in the new structure TableY must contain a reference with TableX, the complete fields of table would
complete fields of table would
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`id_toX` int(10) not NULL,
`D` varchar(45) DEFAULT NULL,
`E` varchar(45) DEFAULT NULL,
How insert the the reference of TableX in TableY of the same record of the TableA???
Alter TableA to contain a unique ID which you can insert into both of the new tables. Use this column to create whatever references you wish, then remove this column if it is no longer needed with another ALTER TABLE.
try:
INSERT INTO TableY (id_toX, D, E)
SELECT DISTINCT t2.id, t1.D, t1.E
FROM TableA as t1
inner join
TableX as t2
on (t1.A=t2.A and t1.B=t2.B and t1.C=t2.C)
Related
I have two tables, the first table has a reference to the id from the second table, I want to make a query involving a left join with fields from the second table as well as with a COUNT function in the select, because of the COUNT function, I am using an GROUP BY clause.
So my query looks something like:
SELECT t1.id, t1.txt, t2.id, t2.txt, COUNT(t2.id)
FROM test_data1 t1
LEFT JOIN test_data2 t2 ON (t1.ref_col = t2.id)
GROUP BY t1.id
In my tables, only the second row of test_data1 has an entry in ref_col, so I would expect that for the first row in the results, the value for t2.id would be NULL, however that is not the case (in my example I see the value 2, but I'm not sure if there might be an element of randomness here).
If I use
SELECT MAX(t1.id), MAX(t1.txt), MAX(t2.id), MAX(t2.txt), COUNT(t2.id)
FROM test_data1 t1
LEFT JOIN test_data2 t2 ON (t1.ref_col = t2.id)
GROUP BY t1.id
I get my expected results, however I am surprised this is necessary given that there will at most only be one entry in test_data2 matching ref_col in test_data1.
Does anyone know why LEFT JOIN + GROUP BY is behaving this way? This is using MySQL version 8 on Linux.
If you want to reproduce this here are the table definitions:
CREATE TABLE test_data1 (id int unsigned NOT NULL AUTO_INCREMENT,
txt VARCHAR(45) DEFAULT NULL,
ref_col int unsigned DEFAULT NULL, PRIMARY KEY (id));
CREATE TABLE test_data1 (id int unsigned NOT NULL AUTO_INCREMENT,
txt VARCHAR(45) DEFAULT NULL,
ref_col int unsigned DEFAULT NULL, PRIMARY KEY (id));
INSERT INTO test_data1 (id, txt, ref_col)
VALUES
(1,'zz',NULL),
(2,'yy',2),
(3,'xx',NULL);
INSERT INTO test_data2 (id, txt)
VALUES
(1,'aa'),
(2,'bb'),
(3,'cc'),
(4,'dd');
I have a table that looks like this:
id int primary key
uniqueID string --not uniquely indexed
foreignKeyID int --foreignKey to another table
I want to find all the uniqueIds in this table that exist for foreign key 1 that do not exist for foreign key 2
I thought I could do something like this:
SELECT * FROM table t1
LEFT JOIN table t2
ON t1.uniqueID = t2.uniqueID
WHERE
t1.foreignKeyID = 1
AND t2.uniqueID IS NULL
However this is never giving me results. I can make it work with a NOT IN subquery but this is a very large table so I suspect a solution using joins will be faster.
Looking for the best way to structure this query.
Here's an sample data set and SQL Fiddle with an example of the working NOT IN query I am trying to convert to a LEFT JOIN:
CREATE TABLE `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uniqueID` varchar(255),
`foreignKeyID` int(5) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `table` (uniqueID, foreignKeyID) VALUES ('aaa', 1), ('bbb', 1);
http://sqlfiddle.com/#!9/48a3f3/4 and a non-working LEFT JOIN I thought would be equivalent.
Thanks!
Try this, seems to be working if understood the question properly:
SELECT *
FROM `table` t
LEFT JOIN `table` tt ON tt.uniqueID = t.uniqueID AND tt.foreignKeyID <> 1
WHERE t.foreignKeyID = 1 AND tt.id IS NULL;
So I'm in a situation where I currently have two tables, that are linked by some foreign key.
`table_a` (
`table_id` int not null,
`important_value varchar(128) not null,
);
`table_b` (
`table_id` int not null,
`table_a_id` int not null,
)
I want to move important_value into table_b, which has a reference to table_a.
Assuming that I use the following alter SQL
alter table `table_b` add column `important_value` varchar(128) not null;
How would I now insert the relevant important_value into table_b given it has reference to table_a_id?
You can use a join:
update table_b b join
table_a a
on b.table_a_id = a.table_id
set b.important_value = a.important_value;
I have two tables, table_a and table_b. table_a has the following schema :
CREATE TABLE table_a (
a_id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
a VARCHAR(255) NOT NULL UNIQUE,
b_id INT(11)
);
and table_b :
CREATE TABLE table_b (
b_id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
b VARCHAR(255) NOT NULL UNIQUE
);
Each element in table_a refers (in table_a.b_id) to one element of table_b.
I want a query that would output every element of table_b for which there are 2 elements or more referencing to it in table_a (and for each row, I'd like it to display how many elements in table_a refer to it)
Thanks
Try this query:
SELECT b.b_id, b.b, t.b_count
FROM table_b b INNER JOIN
(
SELECT a.b_id, COUNT(*) AS b_count
FROM table_a a
GROUP BY a.b_id
HAVING COUNT(*) > 1
) t
ON b.b_id = t.b_id
This avoids a single GROUP BY query which would contain ambiguous columns (and therefore would not run on SQL Server and some other flavors).
I am creating table from two different table with query:
create table post_table as
( select t1.id, t2.url, t2.desc, t2.preview, t2.img_url,
t2.title, t2.hash, t2.rate
from user_record t1, post_data t2
primary key (t1.id, t2,hash))
what's syntax error here?
post_data
----
url varchar(255) No
desc varchar(2048) No
preview varchar(255) No
img_url varchar(128) No
title varchar(128) No
hash varchar(128) No // This is one
rate varchar(20) Yes NULL
user_record
id varchar(40) No //This is 2nd
name varchar(50) Yes NULL
email varchar(50) Yes NULL
picture varchar(50) No
UPDATE:
create table post_table (
id VARCHAR(40), url varchar(255), preview varchar(255) , img_url varchar(128), title varchar(128), hash varchar(128), rate varchar(20)
primary key (t1.id, t2,hash));
select t1.id, t2.url, t2.desc, t2.preview, t2.img_url,
t2.title, t2.hash, t2.rate
from user_record t1, post_data t2;
Formatting the CREATE TABLE statement so we can see the ( ) pairing:
create table post_table as (
select t1.id, t2.url, t2.desc, t2.preview, t2.img_url, t2.title, t2.hash, t2.rate
from user_record t1, post_data t2
primary key (t1.id, t2,hash)
)
We can see that the primary key is being attached to the select statement.
Beyond that there are specific restrictions around general CREATE TABLE syntax can be used in a CREATE TABLE ... SELECT statement.
From: http://dev.mysql.com/doc/refman/5.1/en/create-table-select.html
The ENGINE option is part of the CREATE TABLE statement, and should
not be used following the SELECT; this would result in a syntax error.
The same is true for other CREATE TABLE options such as CHARSET.
You can how ever select keys by using syntax similar to:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (a), KEY(b))
-> ENGINE=MyISAM SELECT b,c FROM test2;
So with your query re-work it to define the column types first, then the keys, then the select statement last. We don't know your data types but it would look something similar to:
create table post_table (
id DATATYPE, url DATATYPE, desc DATATYPE...
primary key (t1.id, t2,hash))
)
select t1.id, t2.url, t2.desc, t2.preview, t2.img_url,
t2.title, t2.hash, t2.rate
from user_record t1, post_data t2
You have put key definition BEFORE select.
Also you can't do key definition without fields, so if you need keys, you have put all table structure.
http://dev.mysql.com/doc/refman/5.1/en/create-table.html
Other way is create index after creating table by use CREATE INDEX