How to do Insert-Select with manual incremental value? - mysql

I have 2 mysql databases
DB1
DB2
I want to select all contact values from contact_mst table under DB1, and then insert all those values inside contact_mst table under DB2. I do not want to copy the contact_id field for some reason and want to keep them incremental, but also do not want them to be AUTO_INCREMENT as I have used 2 primary keys Company_id which is 1 and Contact_id which is auto generated using php code for some specific purpose.
So I made a SQL query for transfering data like this :
INSERT INTO DB2.contactsmaster (Company_id, Contact_id, Contact_person)
SELECT 1, (SELECT COALESCE(MAX(Contact_id),0)+1 FROM DB2.contactsmaster), Contact_person FROM DB1.contact_mst;
Which I think I have done something wrong, as this will not generate new IDS each time and in place will return Contact_id as 1 every time.
Any suggestion?
P.S. I just want to achieve this using SQL Query only. I know I can do this with PHP code but actually I want to supply .sql file to my client.

Below is the sample code for inserting records to table tab2 where value of column a is a sequence of integer and value of column b is same as value of column b of tab1
create table tab1
(
a int,
b int
);
create table tab2
(
a int,
b int
);
insert into tab1
values
(10,20),(30,40);
tab1 contents:
| a | b |
---------
|10 |20 |
|30 |40 |
insert into tab2
select #row := #row + 1, b FROM tab1 , (SELECT #row := 0) r
tab2 contents:
| a | b |
---------
|1 |20 |
|2 |40 |
Check the working of the query at sqlfiddle:
http://www.sqlfiddle.com/#!2/5f9a39/1
Let me know if it solved your problem or not.

try this
INSERT INTO DB2.contactsmaster (Company_id, Contact_id, Contact_person)
VALUES(
1,
(SELECT COALESCE(MAX(Contact_id),0)+1 FROM DB2.contactsmaster),
(SELECT Contact_person FROM DB1.contact_mst LIMIT 1)
)

To insert record with seprate key generate you need to use trigger for insert key
create bellow trigger in db2
CREATE TRIGGER `trg_before_insert` BEFORE INSERT ON `contactsmaster `
FOR EACH ROW
set new.Contact_id =(SELECT COALESCE(MAX(Contact_id),0)+1 FROM contactsmaster)
DELIMITER ;
after trigger created execute bellow sql
INSERT INTO DB2.contactsmaster (Company_id, Contact_person)
SELECT 1, Contact_person FROM DB1.contact_mst;

Related

Creating a table in Mysql dynamically with the AS SELECT

I'm sorry if it's a silly question, but I don't know how to create dynamically an SQL Table.
Let's imagine that I have two tables :
Table1 : nameT1, numberT1, dateT1
The first one isn't dynamically initiated. BUT the second needs to be, and the values in it have different names. So I started with this approach :
CREATE TABLE Table2 (
nameT2 VARCHAR(20),
numberT2 INTEGER(5),
dateT2 DATETIME
) AS SELECT (
nameT1,
numberT1,
dateT1
) FROM Table1;
But I have some problems with the compilation. And I don't know where I define that (for Table2) :
nameT2 = nameT1
numberT2 = numberT1
dateT2 = dateT1
I simplified the problem, normally I have conditions to select which ones I want to insert from Table1 but that's not part of the problem.
A create as select will create the defined columns then append the selected columns. If you want to rename the columns drop the column definitions and use aliases. For example
DROP TABLE IF EXISTS T,T1;
CREATE TABLE T (nameT1 VARCHAR(3),numberT1 INT, dateT1 DATE);
INSERT INTO T VALUES ('AAA',10,'2020-05-15');
CREATE TABLE T1 AS SELECT
nameT1 AS NAMET2,
numberT1 AS NUMBERT2,
dateT1 AS DATET2
FROM T;
SELECT * FROM T1;
+--------+----------+------------+
| NAMET2 | NUMBERT2 | DATET2 |
+--------+----------+------------+
| AAA | 10 | 2020-05-15 |
+--------+----------+------------+
1 row in set (0.001 sec)

selecting a column from multiple tables in mysql

TABLE 1
+----+-------+-------+-------+
| uid | color | brand | model |
+----+-------+-------+-------+
| 10 | 1 | 2 | 1 |
+----+-------+-------+-------+
TABLE 2
+----+-------+-------+-------+
| uid | quantity |model |color|
+----+-------+-------+-------+
| 25 | 2 | 2 | 1 |
+----+-------+-------+-------+
I have many tables like this where the uid column is present in every table.I have a value in a variable, say var1=25. I want to check whether var1 value matches with any of the uid value of any table.If it matches I want to print the table name. Can anyone help me with this?
I tried doing this and I found
SELECT `COLUMN_NAME`
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA`='yourdatabasename'
AND `TABLE_NAME`='yourtablename';
But this is not giving what I want since I want to select all the tables in a database irrespective of the table name.If in future any table is added then it should also get selected.
At first, information_schema table doesn't have specific tuple data.
I suggest you to consider different design.
A. Make a meta table and use triggers(attached to base tables) to maintain meta table.
CREATE TABLE meta_table (
id INT AUTO_INCREMENT,
uid INT,
table_name VARCHAR(50)
);
# When you need to add new table (table 3)
CREATE TABLE table_3 (
uid INT,
field1 INT,
field2 INT,
field3
);
DELIMITER $$
CREATE TRIGGER table_3_insert
AFTER INSERT ON table_3
FOR EACH ROW
BEGIN
INSERT INTO meta_table (uid, table_name)
VALUE (NEW.uid, "table_3");
END$$
DELIMITER ;
# If data in `table_3` might be changed or deleted,
# then create trigger for `delete` and `update`
B. Use only one table with unstructured field and parse data field in your application
CREATE TABLE table (
uid INT,
table_type INT,
data VARCHAR(255)
);
INSERT INTO table (10, 1, '{"color":1,"brand":2,"model":1}');
INSERT INTO table (10, 2, '{"quantity":2,"model":2,"color":1}');
As you mentioned "any table can be added" often, I strongly recommend B solution. It is not good design that changing schema(creating table) often.

Update multiple rows in table with values from a temporary table

I'm trying to write a database migration script to add a column to a table that contains existing data, and then populate that column with appropriate data.
I'm doing the migration in a few steps. I've created a temporary table that contains a single column with ids like this:
new_column
==========
1000
1001
1002
1003
...
I now want to update my existing table so that each row in the temporary table above is used to update each row in my existing table. The existing table looks like this:
old_column_1 | old_column_2 | new_column
========================================
1 | 100 | null
2 | 101 | null
3 | 102 | null
...
I've tried a few variations of this sort of update -
select min(t.new_column)
from temp t
where t.new_column not in (select new_column from existing_table);
But I can't seem to get the syntax right...
Your problem is more complicated than you think. There's nothing reliable to join on. So, either you write a stored procedure which uses a cursor to loop through both tables and updating the existing table row by row (which can quickly become a performance nightmare, therefore I wouldn't recommend it) or you use this a little complicated query:
CREATE TABLE temp
(id int auto_increment primary key, `new_column` int)
;
INSERT INTO temp
(`new_column`)
VALUES
(1000),
(1001),
(1002),
(1003)
;
CREATE TABLE existing
(`old_column_1` int, `old_column_2` int, `new_column` varchar(4))
;
INSERT INTO existing
(`old_column_1`, `old_column_2`, `new_column`)
VALUES
(1, 100, NULL),
(2, 101, NULL),
(3, 102, NULL)
;
update
existing e
inner join (
select * from (
select
t.*
from temp t
)t
inner join
(
select
e.old_column_1, e.old_column_2,
#rownum := #rownum + 1 as rn
from existing e
, (select #rownum:=0) vars
)e on t.id = e.rn
) sq on sq.old_column_1 = e.old_column_1 and sq.old_column_2 = e.old_column_2
set e.new_column = sq.new_column;
see it working live in an sqlfiddle
I added an auto_increment column in your temporary table. Either you do it this way, or you simulate a rownumber like I did here:
select
e.old_column_1, e.old_column_2,
#rownum := #rownum + 1 as rn
from existing e
, (select #rownum:=0) vars
If you want to influence which row gets which row number, you can use ORDER BY whatever_column ASC|DESC in there.
So, what the query basically does, is, to create a row number in your existing table and join it via this column and the auto_increment column in the temporary table. Then I join this subquery again to the existing table, so that we can easily copy the column from temporary table to existing table.

How to program a MySQL trigger to insert rows into another table

I have two tables, one is a users table and another is a connectedto table. The users table loks like so:
USERS_TABLE:
ID | username
1 | usera
2 | userb
The connectedto table looks like so:
CONNECTED_TABLE:
con_id | con_from | con_to
1 | 1 | 2
2 | 2 |1
I want to place a trigger on USERS table such that upon adding of a user in the users table, the connectedto table changes such that the new user is connected to each and every other previous user AND each and every other previous user is connected to the new user. Kindly help.
I see no sense in that, to be honest.
You can easily create your connected_table on the fly like in this example:
create table foo(id int);
insert into foo values (1), (2);
select f1.id, f2.id from foo f1, foo f2
where f1.id != f2.id;
Result:
1 2
2 1
Try with this simple trigger example:
ex:
Two tables like table1 , table2:
Trigger
CREATE TRIGGER TRI_table1
AFTER INSERT ON table1 FOR EACH ROW
INSERT INTO table2 (contact_id, count) VALUES
(new.contact_id,0)
i hope it's use full for you.

Reformatting (reshaping) data table from long to wide using MySQL

New to MySQL and trying to carry something over from R.
I have a data table with two columns, similar to the following, with a level-2 id and a nested id:
level2id | nestedid |
1 | 1 |
1 | 2 |
1 | 3 |
2 | 1 |
2 | 2 |
...
I want to restructure the data using MYSql in a new table like this:
level2id | nestedid1 | nestedid2 | nestedid3 |
1 | 1 | 2 | 3 |
2 | 1 | 2 | |
...
This is so that I can later perform joins to extract information on the nested ids to create aggregate values for variables that relate to the level2 id. Trivial to do in R using reshape for "time-varying" data, but can't find an obvious solution to this particular format (i.e. where the data are not organized in terms of attribute names and attribute values in columns. Thanks in advance!
While you cannot do it as a SELECT you may achieve this using inserts which only works if the primary key ls level2id or you have a unique index on that level2id
Table structure
CREATE TABLE `table2` (
`level2id` int(11) NOT NULL DEFAULT '0',
`nestedid1` int(11) NOT NULL,
`nestedid2` int(11) NOT NULL,
`nestedid3` int(11) NOT NULL,
PRIMARY KEY (`level2id`)
) ENGINE=InnoDB;
The insert SQL statements replace table1 with your old table
INSERT INTO table2 (level2id, nestedid1) SELECT level2id, nestedid FROM table1 WHERE nestedid = 1 ON DUPLICATE KEY UPDATE nestedid1 = nestedid;
INSERT INTO table2 (level2id, nestedid2) SELECT level2id, nestedid FROM table1 WHERE nestedid = 2 ON DUPLICATE KEY UPDATE nestedid2 = nestedid;
INSERT INTO table2 (level2id, nestedid3) SELECT level2id, nestedid FROM table1 WHERE nestedid = 3 ON DUPLICATE KEY UPDATE nestedid3 = nestedid;
The ON DUPLICATE KEY UPDATE is a MySQL extension more details here http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
I had a similar issue.
Maybe you want to have a look at dynamic pivoting in sql.
Dynamic pivot table with multiple columns in sql server. However I really do not recommend if you can just use a reshape command in R.
You may use MySQL to create a MySQL program that will fix this:
USE test;
/*Create long input table 'test' with variables of varying length*/
DROP TABLE nums;
CREATE TABLE nums (id INT(2));
INSERT INTO nums
VALUES
(0), (1), (2), (3), (4), (5), (6), (7);
DROP TABLE test;
CREATE TABLE test (id INT(2), var VARCHAR(5), attribute VARCHAR(6), PRIMARY KEY (id, var));
INSERT INTO test
SELECT nums3.*, REPEAT(CHAR(97+RAND()*24),CAST(6.*RAND() AS INT)) AS attribute
FROM (SELECT DISTINCT nums2.id1 as id, CONCAT('var', LPAD(CAST(16.*RAND() AS INT),2,'0')) AS var
FROM (SELECT DISTINCT nums.id as id1, nums1.id as id2 FROM nums, nums as nums1) AS nums2) AS nums3;
/*Create SQL program to convert long to wide format (R: reshape)*/
SELECT DISTINCT CONCAT('DROP TABLE result;\nCREATE TABLE result (id INT(2),
', GROUP_CONCAT(CONCAT(field) SEPARATOR ', '), ');')
FROM
(SELECT DISTINCT CONCAT(var, CONCAT(' VARCHAR(', max(length(attribute)), ')')) AS field
FROM test GROUP BY var) AS fields
UNION
SELECT CONCAT("INSERT INTO result \nSELECT DISTINCT test.id, ", GROUP_CONCAT(var SEPARATOR '.attribute, '),
".attribute FROM (SELECT DISTINCT id FROM test) AS test")
FROM (SELECT DISTINCT var FROM test ORDER BY var) as vars
UNION
SELECT CONCAT("LEFT JOIN test AS ", var, " ON test.id = ", var, ".id AND ", var, ".var=", '"', var, '"' )
FROM (SELECT DISTINCT var FROM test ORDER BY var) as vars
UNION
SELECT ";" ;
/*Copy output to screen editor, delete '|' symbols and superfluous white spaces.
Then copy to MySQL prompt, run by pressing 'enter' key and view 'result'*/