combine mysql insert with independent WHERE statement - mysql

I have a simple INSERT statement which collects data from a simple html form and another mysql table and inserts all the data into a second mysql table.
mysqli_query($GLOBALS["conn"],
"INSERT INTO `Table2`
(idFI, NameSZ, ColorSZ, TimeSZ, RoomSZ, DateSZ)
SELECT id, FName, ColorFI, '$Time', '$Room', '$Date'
FROM Table1
WHERE id = '$FNameid'")
This works fine so far.
Now I want to add a statement which inserts a value (1, 2 or 3) into Table2 (RowSZ) depending on the time which was inserted in the input field for TimeSZ.
The rules:
below 8:00:00 --> Value 1
between 8:15:00 and 16:00:00 --> Value 2
above 16:15:00 --> Value 3
Example:
I type the time 12:00:00 into the input field (TimeSZ). When I click the submit button I want, together with the rest of the INSERT INTO statement, that it writes the value 2 into the row (RowSZ)
+------+--------+---------+----------+--------+------------+-------+
| idFi | NameSZ | ColorSZ | TimeSZ | RoomSZ | DateSZ | RowSZ |
+------+--------+---------+----------+--------+------------+-------+
| 33 | Namexx | #FFFFFF | 12:00:00 | 2 | 2018-06-30 | 2 |
The value 2 in RowSZ should be inserted automatically depending on the TimeSZ which was typed into the input field of the form.
How can I do it? Thanks!

This can be done in your SQL Insert statement. In your insert, you can calculate the value for RowSZ based on the time value:
INSERT INTO `Table2`
(idFI, NameSZ, ColorSZ, TimeSZ, RoomSZ, DateSZ, RowSZ)
SELECT id, FName, ColorFI, '$Time', '$Room', '$Date', IF('$time' < '08:00:00',1,if('$time' < '15:00:00',2,3))
FROM Table1
WHERE id = '$FNameid'

Related

mysql On Duplicate value in field, insert new row with new value

I want to add a new record in a table if duplicate value enters in a unique field. I don't want to update the existing one but want to add a new record by modifying the unique field value.
Is this possible in mysql?
EDIT:
Edited after user comment on this post:
You need write table locking on both of those two processes.
A WRITE lock has the following features:
The only session that holds the lock of a table can read and write data from the table.
Other sessions cannot read data from and write data to the table until the WRITE lock is released.
Also look at SQL UNIQUE Constraint
BEFORE EDIT:
Yes it is possible. And it took me awhile to figure it out. I build this on your input and compering values as test1, test2 etc, where test is always the same and has trailing number. As you specified.
It can be done as MySQL TRANSACTION in 4 steps.
Lets say you have table testT where name is unique to insure we have no doubles.
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
And you want to insert a new item with name test1 we set is as:
SET #newName = 'test1';
Then we need to check if it already exists in table:
SELECT #check:=COUNT(*) FROM testT WHERE name = #newName;
We do a count here to get true or false and save it as #check here so we can compare it later. This will result into 1 row as test1 already exists in table.
Next we do another selection to get the highest number of test* and store it as #number, this next query selects all tests and does a SUBSTRING after 4 latter's giving us all numbers after first 4 latter's. (99999999999) numbers actually just to be sure we don't miss any but in our case result is only "3" because that is last record "test3" in table.
SELECT
#number:= SUBSTRING(name,5,99999999999)
FROM testT;
Now we can do an insert:
INSERT INTO testT(name)
VALUES
(
IF(#check = "", #newName , CONCAT(LEFT(#newName,4),RIGHT(#number,1)+1)
)
);
This tries to insert our #newName into table under IF condition, and that is if our #check is empty then he will insert #newName, if not it will take word test out of string and append a highest #number from earlier and add + 1 too it.
So result for #newName = 'test1' is below. If you change this into #newName = 'test3' result wold be same new insert test4.
**Schema (MySQL v5.7)**
SET #newName = 'test1';
---
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test4 |
---
And if you change it in ANY test* that number does not already exists it will insert it normally. In case below: #newName = 'test6'
SET #newName = 'test6';
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test6 |
This way an insert will always be made.
You can play with this here : View on DB Fiddle just by changing SET #newName = 'test6'
I am no expert and it took me couple of hours to figure this way out, as I wanted to know if this was even possible.
And I would appreciate if any other user can suggestion any other way or improve my method.

How to change the data of a column in mysql?

I need to change some data of one column from table1 and then, I will copy some of the table1 data to new_table, here is my example tables.
table1
id | url | user1_ign | user2_ign | message | fields that are not needed anymore
new_table
id | url | user1_ign | user2_ign | message
Basically, table1 have fields that are not in new_table. My problem is I do not know how to change the data in a field while copying it to a new table (already searched here).
I need to change the data of the url. Here is the layout.
table1
id | url | user1_ign | user2_ign | message | some field
1 | jj-HasZNsh | jj | gg | hello dude! | ...
new_table
id | url | user1_ign | user2_ign | message
1 | jj-gg-HasZNsh | jj | gg | hello dude!
That is what I needed to do to, as you can see, I need to change the url in new_table based on the user1_ign and user2_ign. Is there a way of how to solve this?
UPDATE
I have this kind of url in table1 number-HasZNsh or alphabet-HasZNsh.
I need them to become like this in new_table
number-HasZNsh -> ign1-ign2-HasZNsh
alphabet-HasZNsh -> ign1-ign2-HasZNsh
This is what I need to do specifically.
You can combine the INSERT statement for your destination table followed SELECT to set the values to be inserted. For your url field as you specify above, you can use REPLACE to replace a string inside a string.
INSERT INTO
`new_table` (id, url, user1_ign, user2_ign, message)
SELECT
id,
REPLACE(url, '-', '-gg-') `url`,
user1_ign,
message
FROM
`table1`
If you wish to grab data from another field for the gg part of the REPLACE line, you would use :
INSERT INTO
`new_table` (id, url, user1_ign, user2_ign, message)
SELECT
id,
REPLACE(url, '-', CONCAT('-', user2_ign, '-') `url`,
user1_ign,
message
FROM
`table1`
For more information on the command syntax as used above :
REPLACE
CONCAT
INSERT INTO table1 FROM table2

Mysql Update / Insert: copying historical data

I have some historical data tables in my Mysql database.
I want to repeat a day's historical data for another day in the same table.
Table structure, with some sample data:
Id | Date | Value
1 | 2012-04-30 | 5
2 | 2012-04-30 | 10
3 | 2012-04-30 | 15
I want to repeat those ids & values, but for a new date - e.g. 2012-05-01. i.e. adding:
1 | 2012-05-01 | 5
2 | 2012-05-01 | 10
3 | 2012-05-01 | 15
I feel that there should be a straightforward way of doing this... I've tried playing with UPDATE statements with sub-queries and using multiple LEFT JOINs, but haven't get there yet.
Any ideas on how I can do this?
EDIT: To clarify...
- I do NOT want to add these to a new table
- Nor do I want to change the existing records in the table.
- The ids are intentionally duplicated (they are a foreign_key to another table that records what the data refers to...).
INSERT INTO yourTable
SELECT ID, "2012-05-01" As Date, Value
FROM yourTable
WHERE Date = "2012-04-31"
Usually, your ID would be an autoincrement though, so having the same ID in the same table would not work. Either use a different ID, or a different table.
Different ID (next autoincrement):
INSERT INTO yourTable
SELECT NULL as ID, "2012-05-01" As Date, Value
FROM yourTable
WHERE Date = "2012-04-31"
Different table (referring to original ID)
INSERT INTO yourTable_hist
SELECT NULL as ID, ID as old_ID, "2012-05-01" As Date, Value
FROM yourTable
WHERE Date = "2012-04-31"
Maybe something like this:
UPDATE Table1
SET Date=DATE_ADD(Date, INTERVAL 1 DAY)
Or if you want to insert them to a new table:
INSERT INTO Table1
SELECT
ID,
DATE_ADD(Date, INTERVAL 1 DAY),
Value
FROM
Table2

Need to insert CSV values in MySQL column to another table

I have a CSV file containing user information:
'Arlington', '1,3,5,7,9'
'StackExchange', '2,3'
And I will need the above information imported like this:
"User" table:
id | name
1 | 'Arlington'
2 | 'StackExchange'
"User groups" table:
id | user_id | group_id
1 | 1 | 1
2 | 1 | 3
3 | 1 | 5
4 | 1 | 7
5 | 1 | 9
6 | 2 | 2
7 | 2 | 3
What's the easiest way to do this? I have imported the data with a temp column holding the CSV values:
id | name | tmp_group_ids
1 | 'Arlington' | '1,3,5,7,9'
2 | 'StackExchange' | '2,3'
I am thinking if I import it this way, I will know exactly what id gets assigned for the user (the id column in the users table is auto_increment), and so I can use that id as user_id for the "user groups" table.
But now how do I get values from tmp_group_ids into the "User groups" table?
Would appreciate any help! Thanks!
the easy way would be a php or perl script.
You can use the MySQL SUBSTRING() function to split the string and insert the different values into the table. You can do this by writing a function or using a stored procedure.
I had recently a similar problem, I used the function SUBSTRING_INDEX(str,delim,count), using "," as delimiter
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring-index
INSERT INTO tableUserGroup (userid, groupid)
SELECT
t1.id
, substring_index(t1.tmp_group_ids,',',2)
, substring_index(t1.tmp_group_ids,',',3)
FROM table1 t1
First, insert the names into the User table - with id autonumber, this will work:
INSERT INTO User
(name)
SELECT DISTINCT
name
FROM TempTable
Then:
--- Create a "numbers" table:
CREATE TABLE num
( i INT PRIMARY KEY
) ;
--- Populate it with numbers:
INSERT INTO num
(i)
VALUES
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
Then, you can use FIND_IN_SET() function which is handy for this situation (splitting comma-separated fields), like this:
INSERT INTO User_Groups
(user_id, group_id)
SELECT
u.id AS user_id
, num.i AS group_id
FROM User AS u
JOIN TempTable AS t
ON t.name = u.name
JOIN num
ON FIND_IN_SET(num.i, t.tmp_group_ids) > 0

Reorder rows in a MySQL table

I have a table:
+--------+-------------------+-----------+
| ID | Name | Order |
+--------+-------------------+-----------+
| 1 | John | 1 |
| 2 | Mike | 3 |
| 3 | Daniel | 4 |
| 4 | Lisa | 2 |
| 5 | Joe | 5 |
+--------+-------------------+-----------+
The order can be changed by admin hence the order column. On the admin side I have a form with a select box Insert After: to entries to the database. What query should I use to order+1 after the inserted column.
I want to do this in a such way that keeps server load to a minimum because this table has 1200 rows at present. Is this the correct way to save an order of the table or is there a better way?
Any help appreciated
EDIT:
Here's what I want to do, thanks to itsmatt:
want to reorder row number 1 to be after row 1100, you plan to leave 2-1100 the same and then modify 1 to be 1101 and increment 1101-1200
You need to do this in two steps:
UPDATE MyTable
SET `Order` = `Order` + 1
WHERE `Order` > (SELECT `Order`
FROM MyTable
WHERE ID = <insert-after-id>);
...which will shift the order number of every row further down the list than the person you're inserting after.
Then:
INSERT INTO MyTable (Name, `Order`)
VALUES (Name, (SELECT `Order` + 1 FROM MyTable WHERE ID = <insert-after-id>));
To insert the new row (assuming ID is auto increment), with an order number of one more than the person you're inserting after.
Just add the new row in any normal way and let a later SELECT use ORDER BY to sort. 1200 rows is infinitesimally small by MySQL standards. You really don't have to (and don't want to) keep the physical table sorted. Instead, use keys and indexes to access the table in a way that will give you what you want.
you can
insert into tablename (name, `order`)
values( 'name', select `order`+1 from tablename where name='name')
you can also you id=id_val in your inner select.
Hopefully this is what you're after, the question isn't altogether clear.