Insert Several Similar Rows with One Query in MySQL - php

Consider a table with 2 fields:
tbl(Id int primary key,Name varchar(100))
Assume that this table contains one row with Id=3 and some unknown Name.
Id | Name
---------------
3 | *****
I have an array of Ids, for example: array(4,6,7,10)
How to put these Ids with the Name of row with Id=3 into this table with one query, So that the resulted table would be:
Id | Name
---------------
3 | *****
----------------
4 | *****
----------------
6 | *****
----------------
7 | *****
----------------
10 | *****
I can not use the Name's value in the query.
I am thinking of a query like this:
insert into tbl(Id,Name) select (4,6,7,10),Name from tbl

You need 2 queries, 1st get the name and 2nd do the insert with multi row insert
INSERT INTO Table ( Column1, Column2 ) VALUES
( Value1, Value2 ), ( Value1, Value2 )

Related

Rewrite of counter by partition

I use mysql and php with phpmyadmin. I have major problem with a partition based counter that I wan't to improve but my knowledge on sql prevents me from doing that. Im struggling very much with this.
I want the duplicated data in my table to have a counter that adds a number after a value if this value gets a duplicated value and then restarts from 1 until a new value is met and so on. Here is what the final result should look like
---------------------------
1 | Josh-1
---------------------------
2 | Josh-2
--------------------------
3 | Josh-3
--------------------------
4 | Josh-4
--------------------------
5 | Fred-1
--------------------------
6 | Fred-2
--------------------------
7 | Fred-3
-------------------------
I had gotten help with this counter here before but it's not working as I wan't it to. Also when I have pressed the insert button in my form the table looks like this in phpmyadmin after I reload it
---------------------------
1 | Josh-1-1-1
---------------------------
2 | Josh-2
--------------------------
3 | Josh-3
--------------------------
4 | Josh-4
--------------------------
5 | Fred-1
--------------------------
6 | Fred-2
--------------------------
7 | Fred
-------------------------
Whats going on here? The code that I seek help with rewriting is this
UPDATE usermeta u1,
(SELECT
u1.`id`, CONCAT(u1.`name`,'-',ROW_NUMBER() OVER(PARTITION BY u1.`name` ORDER BY u1.`id`)) newname
FROM
usermeta u1 JOIN (SELECT `name` , COUNT(*) FROM usermeta GROUP BY `name` HAVING COUNT(*) > 1) u2
ON u1.`name` = u2.`name` ) u3
SET u1.`name` = u3.`newname`
WHERE u1.`id` = u3.`id`
Could this code be rewritten so it creates a table of numbered names and duplicates that looks like the first table example and work like it should in phpmyadmin ? All help is very much appreciated. Keep in mind that I am a struggling moderate sql user.
Possible solution - BEFORE INSERT trigger and additional MyISAM table with secondary autoincrement:
Working table
CREATE TABLE user (id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(127));
Additional table
CREATE TABLE user_index (id INT AUTO_INCREMENT,
name VARCHAR(127),
PRIMARY KEY (name, id)) ENGINE=MyISAM;
Trigger
CREATE TRIGGER insert_user_index
BEFORE INSERT ON user
FOR EACH ROW
BEGIN
DECLARE new_index INT;
INSERT INTO user_index (name) VALUES (NEW.name);
SET new_index = LAST_INSERT_ID();
DELETE FROM user_index WHERE name = NEW.name AND id < new_index;
SET NEW.name = CONCAT_WS('-', NEW.name, new_index);
END
Insert rows - the AI index is added to the name. Check the result.
INSERT INTO user (name) VALUES
('Josh'),
('Josh'),
('Fred'),
('Josh'),
('Fred'),
('Fred'),
('Josh');
SELECT * FROM user;
id | name
-: | :-----
1 | Josh-1
2 | Josh-2
3 | Fred-1
4 | Josh-3
5 | Fred-2
6 | Fred-3
7 | Josh-4
Look what is stored in additional table now.
SELECT * FROM user_index;
id | name
-: | :---
3 | Fred
4 | Josh
db<>fiddle here
If your working table user exists already, and it contains some data, then you'd create additional table and fill it with data using, for example,
CREATE TABLE user_index (id INT AUTO_INCREMENT,
name VARCHAR(127),
PRIMARY KEY (name, id)) ENGINE=MyISAM
SELECT MAX(SUBSTRING_INDEX(name, '-', -1) + 0) id,
SUBSTRING_INDEX(name, '-', 1) name
FROM user
GROUP BY 2;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=38f028cfe1c9e85188ab0454463dcd78

Submit form to fill up the last recent ID row [MySQL] [duplicate]

This question already has an answer here:
MySQL Set AutoIncrement "Ad Hoc"
(1 answer)
Closed 3 years ago.
Lets say I have this table:
------------------
ID | Car |
------------------
25 | Honda |
.. | ... |
.. | ... |
.. | ... |
123 | Toyota |
------------------
How to start fill in at row 124 instead of filling up row 1 til row 24 first? Assuming the ID is auto-incremental value.
Actual problem: my form method post fill up row with ID = 1 instead of ID = 124
If you want preserve the id from 1 to 123 for reserved use and start insert new value for 124, you could set the initial value for AUTO_INCREMENT
ALTER TABLE your_table AUTO_INCREMENT=123;
or directly in your create table
CREATE TABLE your_table () AUTO_INCREMENT = 123;
then if you insert a value with a null value for id, the auto increment should be 124
insert into your_table (car) values ('my_124 car');

UPDATE using JOIN appends only first row value to another table, why?

I have a target table which crossed over 1M rows. Each time I will be getting 50K rows which may contain multiple duplicated entries. Hence I have decided to store CSV data into a temp table, then from temp_table to target_table by comparing rows between two tables...
If duplicated entries found append data from temp_table to target_table else Insert into the table... I am using partition here, so ON DUPLICATE key update is not working here.. in temp_table I am not using any KEYS
I have two tables which look like below
temp_table
Name | Type
John | Civil
John | Mech
target_table
Name | Type
John | Civil
When I run below query, I am getting an output of single row
UPDATE target_table JOIN temp_table
ON temp_table.Name = target_table.Name
SET target_table.Type = IF((LOCATE(temp_table.Type, target_table.Type) > 0)
target_table.Type,CONCAT(target_table.Type,',',temp_table.Type))
target_table
Name | Type
John | Civil
I am expecting output to be like below
target_table
Name | Type
John | Civil, Mech
May I know where it went wrong?
you should use a group_concat and use a subquery in join
UPDATE target_table
JOIN (
select name, group_concat(Type) grouped
from temp_table
group by name
) t ON t.Name = target_table.Name
SET target_table.Type = t.grouped
I suspect (but don't know for sure) and hopefully someone who does know will jump in and correct me, that an update join does not create a cartesian product in the way that a select would. As an attempted proof
truncate table temp_table;
insert into temp_table values
( 'John' , 'mech' ),
( 'John' , 'abc' );
truncate table target_table;
insert into target_table values
('john', 'civil', 9 );
UPDATE target_table JOIN temp_table
ON temp_table.Name = target_table.Name
set target_table.type = (concat(target_table.Type,',',temp_table.Type));
select * from target_table;
+------+------------+------+
| Name | Type | LOC |
+------+------------+------+
| john | civil,mech | 9 |
+------+------------+------+
1 row in set (0.00 sec)
note that abc from temp_table is ignored and mech is selected purely by chance.
if we change the order in temp_table
truncate table temp_table;
insert into temp_table values
( 'John' , 'abc' ),
( 'John' , 'mech' );
truncate table target_table;
insert into target_table values
('john', 'civil', 9 );
UPDATE target_table JOIN temp_table
ON temp_table.Name = target_table.Name
set target_table.type = (concat(target_table.Type,',',temp_table.Type));
select * from target_table;
we get
+------+-----------+------+
| Name | Type | LOC |
+------+-----------+------+
| john | civil,abc | 9 |
+------+-----------+------+
1 row in set (0.02 sec)
where abc is picked purely by chance.
In my view the safest way to do this is on a row by row basis ie a cursor.

multiple rows update or insert mysql

I've created a table like this,
id | option_name | value | user_id
----------------------------------------------
1 | name | Joe | 1
----------------------------------------------
2 | age | 30 | 1
----------------------------------------------
3 | sex | male | 1
----------------------------------------------
4 | name | Jane | 2
----------------------------------------------
5 | age | 28 | 2
----------------------------------------------
6 | sex | female | 2
----------------------------------------------
I want to update all rows corresponding of user_id and option_name.
If user_id == 3, when i submit form with option_name (name,sex,age) as fields, if there is no rows with user_id == 3 then insert rows but if rows exist i want to update those row with new values for value field.
Please check my code: http://pastebin.com/THQdYpix
I want to reduce query steps in my code, any idea?
First check if it updates or note if the mysql_query() returns false then you can use insert query and execute the query.
Use INSERT ... ON DUPLICATE KEY UPDATE.If you want to do this in a single statement, I would recommend using the INSERT ... ON DUPLICATE KEY UPDATE syntax, as follows:
INSERT INTO table (id, someothervalue) VALUES (1, 'hi mom') ON DUPLICATE KEY UPDATE someothervalue = 'hi mom';
The initial INSERT statement will execute if there is no existing record with the specified key value (either primary key or unique). If a record already exists, the following UPDATE statement (someothervalue = 3) is executed.
Below query will work.
REPLACE INTO `table1`
( `name`,`sex`,`age` )
VALUES
( 'Mark', '29', 'male' )
ON DUPLICATE KEY UPDATE user_id=3;

save and fetch multiple drop down values as comma seperated string in a single database column

i have a drop down box, in which opiton values and id are fetched from database table:
First table:
----------
id | value
----------
1 | Value1
2 | Value2
3 | Value3
-----------
<option id=1>Value1</option>
<option id=2>Value2</optoin>
<option id=3>Value3</option>
Now i want to save the ids of selected values like this
Second Table: (let us assume i selected first two options)
id | Selected
-------------
1 | 1,2
------------
Now, i want to fetch the the string and show the corresponding selected options
any suggestions???
$query = 'SELECT value FROM firsttable WHERE id IN (' . $fieldvalue . ')';
Just retreive the value from the database and put it in the query, it's already formatted as IN wants. Then do a loop through the results and all.
Don't insert them in single column as comma separated instead add a row for each selection.
id | Selected
-------------
1 | 1
2 | 2
------------

Categories