SQL query to create many-to-one tables from one table? - sql-server-2008

I have a table like so:
column1 column2
------- -------
key1 value1
key1 value2
key1 value3
key2 value4
key2 value5
key2 value6
I would like to create the following two tables:
id column1
-- -------
1 key1
2 key2
key_id column2
------ -------
1 value1
1 value2
1 value3
2 value4
2 value5
2 value6
That is, I would like to split a table into a many-to-one relation between two new tables.
How would I write an SQL query to do this?

Assuming the id column in your first new table is an identity column:
INSERT INTO NewTable1
(column1)
SELECT DISTINCT column1
FROM OldTable;
INSERT INTO NewTable2
(key_id, column2)
SELECT n1.id, o.column2
FROM OldTable o
INNER JOIN NewTable1 n1
ON o.column1 = n1.column1;

Why don’t u use php my admin and enter the data manually. It will write the php for you.
Also your id field on each table must always be unique and auto incremented.
you cannot use 111 222 in a primary key

Related

Mysql collapse/merge rows

I have a table with data that looks like this:
ID Name Field2 Field3
1 Steve Value1 <null>
1 Steve <null> Value2
How do I merge these rows into one row that looks like this:
1 Steve Value1 Value2
The row count for ID/Name might vary.
select id, name, max(field2), max(field3)
from your_table
group by id, name

MySQL: Delete records based on maximum value

I have a table containing two foreign keys. I need to delete all rows where key1 & key2 are the same, but val < $x.
key1 & key2 aren't distinct values; there can be multiple records with the same key1 and/or key1/key2 pair.
I've tried several approaches, but can't get anything to work. Every approach thus far results in a MySQL error (such as "can't reopen table") or an incorrect result.
Sample data from the table:
rownum key1 key2 val col col2 col3 col4
1 123 1 2 a b c d
2 123 1 2 e f g h
3 123 2 3 i j k l
4 123 2 3 m n o p
5 456 1 1 q r s t
I need to delete all rows where "val" is < the highest "val" for any given key1/key2 pair.
In other words, for each distinct key1/key2 combo, I need to find the max "val" ($x), and delete any row where val is < $x.
Thus, the desired output after the delete statement is:
rownum key1 key2 val col col2 col3 col4
3 123 2 3 i j k l
4 123 2 3 m n o p
5 456 1 1 q r s t
(col-col4 are irrelevant in determining what records to delete, I included them only to note that the table includes additional columns.)
key1, key2, and "val" are all int type.
How can I delete rows where key1 & key2 are the same, but val < $x?
Use a multi-table delete syntax in which you join the table on itself using the key fields:
DELETE t1 FROM table1 t1, table1 t2
WHERE t1.key1=t2.key1 AND t1.key2=t2.key2 AND t1.val < t2.val
Sqlfiddle - I modified the sample data to have different vals for key pairs.
I'm not sure what your primary key is so I'm just going to call it primary_key
First we need to find the max of key2 for each key1
SELECT key1 as fk1, max(key2) as max_key2 from table group by key1
Then all rows where key2 < max_key2
SELECT t.primary_key as id, s.fk1, s.max_key2, t.key1 from table as t, (SELECT key1 as fk1, max(key2) as max_key2 from table group by key1) as s WHERE t.key2 < s.max_key2 AND s.fk1 = t.key1
Then delete those rows
DELETE from table where primary_key in (SELECT id from (SELECT t.primary_key as id, s.fk1, s.max_key2, t.key1 from table as t, (SELECT key1 as fk1, max(key2) as max_key2 from table group by key1) as s WHERE t.key2 < s.max_key2 AND s.fk1 = t.key1))
I have not tested this but it's roughly how i would go about the problem.
It should go without saying but validate before you delete and have backups

How to select values that already exists in column

I need to select all rows by value that posted more than one time.
Table:
key | value
------------
key1 | value
key2 | value
key2 | value
key3 | value
key3 | value
key4 | value
I need result like:
key2 | value
key3 | value
The below should get you what you need.
select key
from table
group by key
having count(*) > 1;
To find "duplicate" values of key, along with one of the values of value:
SELECT t.key
, MAX(t.value)
FROM mytable t
GROUP BY t.key
HAVING COUNT(1) > 1
To get (key,value) tuples that have "duplicates" in the table:
SELECT t.key
, t.value
FROM mytable t
GROUP
BY t.key
, t.value
HAVING COUNT(1) > 1

mysql copy one row data into multiple rows

I have a table such as:
PK FK Value1 value2 value3
1 1 3 2 5
2 2 5 3 6
4 1 9 null 5
I want a query to copy all rows into resulting table, except those that have a null value.
Resulting in:
PK(above table) value(PK)
1 3
1 2
1 5
2 5
2 3
2 6
4 9
4 5
One way is to do it as three inserts, controlled by a transaction if you need atomicity on the operation:
begin
insert into newtable (pk, value) select pk, value1 from oldtable
where value1 is not null
insert into newtable (pk, value) select pk, value2 from oldtable
where value2 is not null
insert into newtable (pk, value) select pk, value3 from oldtable
where value3 is not null
commit
That's of course assuming your primary key on the new table crosses both columns (I suspect it is since your second column has pk as well). If it's just on pk, no solution is going to work since you'll have a primary key constraint violation.
You can also do it as a union:
insert into newtable (pk, value)
select pk, value1 from oldtable where value1 is not null
union select pk, value2 from oldtable where value2 is not null
union select pk, value3 from oldtable where value3 is not null
You can wirte below queries to achive this
INSERT INTO TABLE2 (SELECT ID,VALUE1 FROM table1);
INSERT INTO TABLE2 (SELECT ID,VALUE2 FROM table1);
INSERT INTO TABLE2 (SELECT ID,VALUE3 from table1);
If you need Single query then you can use
INSERT INTO TABLE2 (SELECT ID,COLUMN1 FROM table1 UNION SELECT ID,COLUMN2 FROM table1 UNION SELECT ID,COLUMN3 from table1)

Hiding new column (alias column)

I have a mysql table that looks like this:
id col2 col3 col4
1 value1 value2 3534
2 value1 value1 8456
3 value1 value2 3566
4 value1 value3 7345
5 value2 value3 6734
What I wanted to do is, select distinct col2+col3 values
id col2 col3 col4
1 value1 value2 3534
2 value1 value1 8456
4 value1 value3 7345
5 value2 value3 6734
I used below query, I get desired result as shown here.
SELECT distinct(CONCAT(col2, col3)) as "dummy column", id, col2, col3, col4
FROM yourtable
GROUP BY CONCAT(col2, col3);
My question is,
As I don't want to display column "dummy column" in output table, how can I hide the same?
This question is related to SO older question
Selecting distinct 2 columns combination in mysql
Why aren't you trying the following?
SELECT id, col2, col3, col4
FROM yourtable
GROUP BY col2, col3