Update Column by Parsing String from Other Column in MYSQL - mysql

I would like to create a new column in a MYSQL table based on the string values in an existing column.
My strategy is to first create an empty column and then update the values in the new column based on values in the existing column. However, I am stumbling on how to parse the string in order to extract the correct values.
The string is of the form 1.1.25. I want to extract the value before the first period and the value between the two periods and put these in new columns.
mytable
id|actsceneline|text
1 |1.1.1 |How are you.
1 |1.1.2 |Not bad. You?
To create the new empty column
ALTER TABLE mytable
ADD COLUMN act VARCHAR(6) NOT NULL,
ADD COLUMN scene VARCHAR(6) NOT NULL
To change the values in the new columns, I imagine I would do something like:
UPDATE mytable SET act = '1',scene = 1
And then use MYSQL string functions such as instr or substr or regex to extract the values and update the new columns as in.
UPDATE mytable SET act =
SELECT SUBSTR(actsceneline, 1, LOCATE('.', text)) FROM mytable
However, I'm struggling with how to extract the values from the string.
Thanks for any suggestions.

Try using SUBSTRING_INDEX():
UPDATE mytable
SET act = SUBSTRING_INDEX(actsceneline, '.', 1),
scene = SUBSTRING_INDEX(SUBSTRING_INDEX(actsceneline, '.', 2), '.', -1);
Result given your data:
mysql> select * from mytable;
+----+--------------+---------------+-----+-------+
| id | actsceneline | text | act | scene |
+----+--------------+---------------+-----+-------+
| 1 | 1.1.1 | How are you. | 1 | 1 |
| 2 | 1.1.2 | Not bad. You? | 1 | 1 |
+----+--------------+---------------+-----+-------+

Best way to create a select and what you want to update.
create a new table from your existing table.
"create table destinationtablename
select * from sourcetable;"
then work on your destinationtablename.
All work finished then check twice before update to original table or you can also take backup of your data by creating new table.

Related

INSERT INTO WHERE LIKE Condition

I am working on a trigger which needs INSERT INTO with WHERE LIKE logic.
I have one table :
Tabel test;
idDocument = varchar(32) idUnit = varchar(3)
-----------------------------
| idDocument | idUnit |
-----------------------------
| AA/2021/KK | NULL |
| AA/2021/JJ | NULL |
| BB/2021/KK | NULL |
| CC/2021/JB | NULL |
-----------------------------
How to INSERT INTO using WHERE LIKE Condition and myquery still ERROR.
myquery :
INSERT INTO test ('idUnit') Values ('111') WHERE idDocument LIKE
'%KK%'
Normally to update existing rows with a new value you'd do something like this:
UPDATE test SET idUnit='111' WHERE idDocument LIKE '%KK%'
This will not insert data, it will only alter existing data.
Note:
INSERT is specifically for adding new rows of data
UPDATE is exclusively for updating existing rows with new data
You can't conditionally add new rows. You either add them or you don't. You can conditionally update or delete them.
Don't think about it in terms of inserting new data, always think in terms of rows and columns which is how SQL works.

Process TEXT BLOBs fields in MySQL line by line

I have a MEDIUMTEXT blob in a table, which contains paths, separated by new line characters. I'd like to add a "/" to the begging of each line if it is not already there. Is there a way to write a query to do this with built-in procedures?
I suppose an alternative would be to write a Python script to get the field, convert to a List, process each line and update the record. There aren't that many records in the DB, so I can take the processing delay (if it doesn't lock the entire DB or table). About 8K+ rows.
Either way would be fine. If second option is recommended, do I need to know of specific locking schematics before getting into this -- as this would be run on a live prod DB (of course, I'd take a DB snapshot). But in place updates would be best to not have downtime.
Demo:
mysql> create table mytable (id int primary key, t text );
mysql> insert into mytable values (1, 'path1\npath2\npath3');
mysql> select * from mytable;
+----+-------------------+
| id | t |
+----+-------------------+
| 1 | path1
path2
path3 |
+----+-------------------+
1 row in set (0.00 sec)
mysql> update mytable set t = concat('/', replace(t, '\n', '\n/'));
mysql> select * from mytable;
+----+----------------------+
| id | t |
+----+----------------------+
| 1 | /path1
/path2
/path3 |
+----+----------------------+
However, I would strongly recommend to store each path on its own row, so you don't have to think about this. In SQL, each column should store one value per row, not a set of values.

Update table row value to a random row value from another table

I have 2 MySQL tables.
One table has a column that lists all the states
colStates | column2 | column 3
------------------------------
AK | stuff | stuff
AL | stuff | stuff
AR | stuff | stuff
etc.. | etc.. | etc..
The second table has a column(randomStates) with all NULL values that need to be populated with a randomly selected state abbreviation.
Something like...
UPDATE mytable SET `randomStates`= randomly selected state value WHERE randomStates IS NULL
Can someone help me with this statement. I have looked around at other posts, but I don't understand them.
this works for me with trial data in SQLite:
UPDATE mytable
SET randomStates = (SELECT colStates FROM
(SELECT * FROM first_table ORDER BY RANDOM())
WHERE randomStates IS NULL)
without the first SELECT portion, you end up with the same random value inserted into all the NULL randomStates field. (i.e. if you just do SELECT StateValue FROM counts ORDER BY RANDOM() you don't get what you want).

SELECT(MAX) not going past 10 - mysql with phpmyadmin

I'm creating a PHP script to insert rows into a database called orders based on a shopping cart that is stored in an associative array using a sessional array $_SESSION['cart']. The database looks something like this:
orders
----------+--------------+-------------+-------------+-------------+
Id | Username | Item1Id | Item2Id | Item3Id |
----------+--------------+-------------+-------------+-------------+
1 | a#aa.com | 8000001 | 8000002 | 800003 |
----------+--------------+-------------+-------------+-------------+
5 | a#aa.com | 7000001 | 6000002 | 700003 |
----------+--------------+-------------+-------------+-------------+
7 | b#bb.com | 8000001 | 8000002 | NULL |
----------+--------------+-------------+-------------+-------------+
10 | a#aa.com | 3000001 | 1000002 | 800009 |
----------+--------------+-------------+-------------+-------------+
Id column type is CHAR(20) as I may choose to use letters later on.
As part of inserting the row, I need to assign an Id (Primary Key) to the order row which will be set to 1 higher than the current highest Id number found.
The whole script works perfectly; query finds highest Id in the table and I increment that by 1 and assign it to a variable to use as part of the insert query. The only problem is that "SELECT MAX(Id) FROM orders" can't seem to find anything higher than 9. Is there a condition which prevents the SELECT MAX(Id) from identifying anything in double digits?
I've got it written like:
$highestID = mysqli_query($conn, "SELECT MAX(Id) FROM orders");
$orderID = $highestID +1;
I've emptied the database except for Id numbers1 and 2. Running the PHP script inserts new rows with Id numbers 3, 4, 5 except when it gets to 10, the script is unable to as it produces an error of having duplicate primary key of '10' (from $orderID's value). Even when manually entering a row into the database with Id of '25', $orderID still only returns '10' when I echo out its result.
I have not set any specific limits to the amount of rows that can be entered or anything like that.
Id is char(20) so order by Id using string sort. You could use cast or convert function to sort numbers.
Like:
select max(cast(Id as unsigned)) from orders
You really do not need to go through ALL that trouble for an auto-incremental PK. Here's how you can go about it.
Step 1 : In your phpmyadmin, edit your table, and check the A_I checkbox for your PK column.
Step 2 : While inserting from PHP, leave the field blank. It will automatically assign a value of the current max + 1 to your PK.
Eg,
$query = "Insert into mytable (id, name) values ('', 'Name1'), ('', 'Name2')";
Edit : You really cannot have a CHAR(20) PK and then expect the increment to work btw.

Mysql auto_increment proceed with lowest value

My problem is: I have a table with an auto_increment column. When I insert some values, all is right.
Insert first row : ID 1
Insert second row : ID 2
Now I want to insert a row at ID 10.
My problem is, that after this there are only rows inserted after ID 10 (which is the normal behaviour ).
But I want that the database first fills up ID 3-9 before making that.
Any suggestions?
EDIT:
To clarify: this is for an URL shortener I want to build for myself.
I convert the id to a word(a-zA-z0-9) for searching, and for saving in the database I convert it to a number which is the ID of the table.
The Problem is now:
I shorten the first link (without a name) -> ID is 1 and the automatically name is 1 converted to a-zA-Z0-9 which is a
Next the same happenes -> ID is 2 and the name is b, which is 2 converted.
Next interesting, somebody want to name the link test -> ID is 4597691 which is the converted test
Now if somebody adds another link with no name -> ID is 4597692 which would be tesu because the number is converted.
I want that new rows will be automatically inserted at the last gap that was made (here 3)
You could have another integer column for URL IDs.
Your process then might look like this:
If a default name is generated for a link, then you simply insert a new row, fill the URL ID column with the auto-increment value, then convert the result to the corresponding name.
If a custom name is specified for a URL, then, after inserting a row, the URL ID column would be filled with the number obtained from converting the chosen name to an integer.
And so on. When looking up for integer IDs, you would then use the URL ID column, not the table auto-increment column.
If I'm missing something, please let me know.
You could do 6 dummy inserts and delete/update them later as you need. The concept of the auto increment, by design, is meant to limit the application's or user's control over the number to ensure a unique value for every single record entered into the table.
ALTER TABLE MY_TABLE AUTO_INCREMENT = 3;
You would have to find first unused id, store it as user variable, use as id for insert.
SELECT #id := t1.id +1
FROM sometable t1 LEFT JOIN sometable t2
ON t2.id = t1.id +1 WHERE t2.id IS NULL LIMIT 1;
INSERT INTO sometable(id, col1, col2, ... ) VALUES(#id, 'aaa', 'bbb', ... );
You will have to run both queries for every insert if you still have gaps, its up to you to decide whether it is worth doing it.
not 100% sure what you're trying to achieve but something like this might work:
drop table if exists foo;
create table foo
(
id int unsigned not null auto_increment primary key,
row_id tinyint unsigned unique not null default 0
)
engine=innodb;
insert into foo (row_id) values (1),(2),(10),(3),(7),(5);
select * from foo order by row_id;
+----+--------+
| id | row_id |
+----+--------+
| 1 | 1 |
| 2 | 2 |
| 4 | 3 |
| 6 | 5 |
| 5 | 7 |
| 3 | 10 |
+----+--------+
6 rows in set (0.00 sec)