I'm trying to figure out a safe way (if possible) to take the "url" column and copy it into the "company" column ... but I don't just want to copy the whole thing - let me try to explain.
I want to copy the company name like for example: apple, mircosoft..etc (from the path) and place them into their company column (to the left). I have about 5000+ results that need to be done and done safety. They all have the same file path structure with "../../images...."
Could I use something like UPDATE with SET?
UPDATE table SET company = url
Thanks for an feedback! I really appreciate it!
You can pick out the N left-most "fields" in a string separated by a character of your choice.
SELECT SUBSTRING_INDEX(url, '/', 4)
FROM mytable
LIMIT 10;
Returns:
../../images/apple
etc.
Then use a -1 to get the right-most field of that result to get the last one.
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(url, '/', 4), '/', -1)
FROM mytable
LIMIT 10;
Returns:
apple
Once you are happy with the expression, use it in an UPDATE:
UPDATE mytable SET company =
SUBSTRING_INDEX(SUBSTRING_INDEX(url, '/', 4), '/', -1);
See https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_substring-index
In mysql 8 you can use the regexp_substr function to use a regular expression to find a substring. Something like:
SELECT REGEXP_SUBSTR(url, '[^/]+', 14) FROM table;
Which would find any character that is not a / but starting at character 14 (part right after your leading ../../...etc string.
I'm working on a project using the pages in php / mysql and html; I have a table that contains the data for calls made from a PBX and save the number called, the source, date, time, etc ... what I want to do is to search within this table all the phone numbers that have the first 4 digits equal to those that pass through the query, only that i have no idea how to pull off only the 4-digit or at least how to make a control character by character of the value contained in the field. I tell you now that the field is a varchar. Thank you in advance :)
To do that in MySQL query, either
SELECT *
FROM <tablename>
WHERE LEFT(<column>, 4) = "<4 digits>"
or
SELECT *
FROM <tablename>
WHERE <column> LIKE "<4 digits>%"
or in the PHP side :
if (strpos($column,'<4 digit>') !== false) {
echo 'true';
}
Use this, to get substring
SELECT aut_name,
RIGHT(aut_name,7)
FROM author
WHERE country='UK';
See more at: http://www.w3resource.com/mysql/string-functions/mysql-right-function.php#sthash.xKNwZeki.dpuf
I suggest this solution:
$variableWhereYoustoreTheFourDigits="1234"; //Use whatever you have in your code to set the value.
$result =$mysqli->query("SELECT number FROM yourtable where number LIKE \"$variableWhereYoustoreTheFourDigits%\");
Context and goal
In table clients I have a column clientNum CHAR(11) NOT NULL with UNIQUE KEY constraint. It contains client number in the format xxx-xxx-xxx where x is a decimal digit. For more details on the format see below.
I want to implement something like AUTO_INCREMENT for this column so that each client gets their number calculated automatically. From MySQL CREATE TABLE docs:
An integer or floating-point column can have the additional attribute AUTO_INCREMENT. When you insert a value of NULL (recommended) or 0 into an indexed AUTO_INCREMENT column, the column is set to the next sequence value. Typically this is value+1, where value is the largest value for the column currently in the table. AUTO_INCREMENT sequences begin with 1.
So I want to find the next number available and use it as clientNum value for newly inserted client row. Next number available is current maximum of clientNum incremented.
I’m coding in PHP using PDO to access the MySQL database (see PDO Tutorial for MySQL Developers).
Client number format
As stated above, the client number is in format xxx-xxx-xxx where x is a decimal digit. The range of each segment is 000 to 999. It is basically a 9-digit integer with leading zeroes and dash as thousands separator. It cannot get above 999-999-999.
Currently we want it be even more restricted, specifically in format 000-1xx-xxx (between 000-100-000 and 000-199-999). But there are already some numbers in the database that can start anywhere from 000-000-001 to 500-000-000.
Unfortunately it has to be stored in this format, I cannot change it.
Finding maximum
I need to get the max number in range 000-100-000 to 000-199-999, values outside this range must be ignored. This is where my problem comes in because as said before some numbers already exist above this.
Maximum is never 000-199-999. Otherwise in would result in adding 000-200-000 and the next time called maximum will be 000-199-999 again, resulting in attempt to insert 000-200-000 again.
How incrementation works
In PHP in can be done like this:
$clientNum = "000-100-000";
$clientNum = str_replace("-", "", $clientNum);
$clientNum++;
$clientNum = implode("-", str_split(str_pad($clientNum, 9, "0", STR_PAD_LEFT), 3));
Final $clientNum value is 000-100-001.
When the initial number is 000-120-015 then the code above produces 000-120-016. Overflow propagates to the next segment, i.e. 000-100-999 becomes 000-101-000. 999-999-999 cannot be incremented.
Idea to start with
In a loop I want to get the next number available, check if that number exists in the database, and if so, redo that loop until it finds an unused number. I know how to check if it’s in the database the first time, but I’m not sure how to do the loop.
Does anyone know a way to do this?
You may want to solve this in SQL, because otherwise you need two transactions (one for reading, one for writing) and meanwhile the number could be used by a concurrent access.
In MySQL, you can use this SQL reimplementation of your PHP code:
INSERT(INSERT(LPAD(CAST(CAST(REPLACE(clientNum, '-', '') as UNSIGNED) + 1 as CHAR), 9, '0'), 7, 0, '-'), 4, 0, '-')
This increments 000-000-999 to 000-001-000 and 999-999-999 to 100-000-000 (truncated from 100-000-0000 by LPAD()). I warned you.
E.g. to just preview what the next value is, use
SELECT INSERT(INSERT(LPAD(CAST(CAST(REPLACE(clientNum, '-', '') as UNSIGNED) + 1 as CHAR), 9, '0'), 7, 0, '-'), 4, 0, '-') FROM clients
If you want to use this when inserting a new row, it is used like this:
INSERT
INTO clients(clientNum, name)
SELECT
INSERT(INSERT(LPAD(CAST(
COALESCE(MAX(CAST(REPLACE(clientNum, '-', '') AS UNSIGNED)), 0) + 1
AS CHAR), 9, '0'), 7, 0, '-'), 4, 0, '-'),
'John Doe'
FROM clients
This works regardless of what API you use to access the database, as long as it is MySQL database. The database does the computation. However, it does not work if clients is a temporary table, which I expect it not to be. More on that below.
See also string functions, CAST(), COALESCE() and INSERT … SELECT in MySQL manual.
Later you added that the permitted values are from range 000-100-000 to 000-199-999. Other values shall be ignored for the purpose of finding maximum. A WHERE clause must be added to the SELECT part of INSERT written above.
INSERT
INTO clients(clientNum, name)
SELECT
INSERT(INSERT(LPAD(CAST(
COALESCE(MAX(CAST(REPLACE(clientNum, '-', '') AS UNSIGNED)), 0) + 1
AS CHAR), 9, '0'), 7, 0, '-'), 4, 0, '-'),
'John Doe'
FROM clients
WHERE clientNum BETWEEN '000-100-000' AND '000-199-999'
Then you stated that my solution does not work for you and proposed a supposed fix:
INSERT
INTO clients(clientNum, name)
VALUES
(SELECT
INSERT(INSERT(LPAD(CAST(
COALESCE(MAX(CAST(REPLACE(clientNum, '-', '') AS UNSIGNED)), 0) + 1
AS CHAR), 9, '0'), 7, 0, '-'), 4, 0, '-')
FROM clients AS tmptable
WHERE clientNum BETWEEN '000-100-000' AND '000-199-999'),
'John Doe'
This uses a subquery instead of the INSERT … SELECT syntax.
In MySQL, table cannot be modified (by INSERT in this case) and read by a subquery at the same time. Quoting the subquery manual:
In MySQL, you cannot modify a table and select from the same table in a subquery. This applies to statements such as DELETE, INSERT, REPLACE, UPDATE, and (because subqueries can be used in the SET clause) LOAD DATA INFILE.
However, you found a workaround using a temporary table. A temporary table is used when an alias (in this case clients AS tmptable) is defined, which evades reading from and writing to the same table at the same time. You used temporary table to store the original table, the article describing the workaround uses it to store the result of the subquery (which is more efficient, I guess). Both approaches work.
At this point I want to point out that my solution should work (and works for me!) too except for the improbable case when clients is a temporary table. I think I can expect it not to be one. Quoting the INSERT … SELECT manual page:
When selecting from and inserting into a table at the same time, MySQL creates a temporary table to hold the rows from the SELECT and then inserts those rows into the target table. However, it remains true that you cannot use INSERT INTO t ... SELECT ... FROM t when t is a TEMPORARY table, because TEMPORARY tables cannot be referred to twice in the same statement (see Section C.5.7.2, “TEMPORARY Table Problems”).
As for me this is explicitly saying that my original approach using INSERT … SELECT should work.
Just to provide a complete answer, I’ll address your original request for PHP solution using database polling. Once more I must add that this is certainly not a good solution.
Your clientNum column must be a unique key. You need to repeat the following steps until successful update:
Get the current maximum of clientNum.
Increment the obtained value.
Try to insert the row.
If successful, finish, otherwise throw the clientNum max value away and loop.
The insertion will fail due to violation of the aforementioned unique key constraint. This happens when another connection to the database successfully performs an insert in the meantime between steps 1. and 3..
You should prepare the statement outside the loop using PDO::prepare() and then execute it in the loop. The return value of execute method indicates success (true) or failure (false).
This is enough info to implement step 3.. Steps 1. and 2. consist of fetching the result of
SELECT MAX(clientNum) FROM clients
and running it through the code provided by Stephanus Yanaputra. Step 4. is a simple loop condition using the return value from execution of INSERT query in step 3..
<?php
mysql_connect(....);
mysql_select_db($db_name);
$res=mysql_query("select ClientNum from ClientTable");
$name_arr=array();
while($row=mysql_fetch_array($res))
{
foreach($row as $name)
$name_arr[]=$name;
}
$clientNum="000-000-000";
while(true){
$clientNum = str_replace("-", "", $clientNum);
$clientNum++;
if($clientNum>999999999)
{
echo("No mismatch found");
break;
}
$clientNum = implode("-", str_split($clientNum, 3));
if(!in_array($clientNum, $name_arr))
{
echo "The first unmatched clientNum is:".$clientNum;//This is what you want.
break;
}
}
?>
Comments
The query execution only once i.e. outside the while loop makes it less time complex. The time complexity is reduced due to use of array instead of execution of the query itself multiple times because searching in an array is comparatively very less time complex than searching in the database.
An easy solution based on function that you provided.
Change the function name rawr() to any naming that you like. (I couldn't find the best name and ended up using some gibberish name lol).
function rawr($in)
{
$num = str_replace("-", "", $in);
$num++;
// Convert back
$str = (string) $num;
// Add Leading 0
while(strlen($str) < 9)
{
$str = "0" . $str;
}
echo $str . "<br />";
$final = substr($str,0,3) . "-" . substr($str,3,3) . "-" . substr($str,6,3);
return $final;
}
To test it, try this code:
echo rawr(0);
echo "<br />";
echo rawr("000-000-000");
echo "<br />";
echo rawr("012-345-678");
echo "<br />";
echo rawr("123-456-789");
echo "<br />";
This will give an output that you desire. However you will have to code it yourself to test the database. In my opinion, this is not the best way to solve your problem, but it should work :)
Scenario:
I have a MySql Database called "tblreqslipdetails" it has a field "subtotals" which has a value = Integer (ex. 4500.50, 2500, 3500.57.. so on..) it also has a field which has "idcategory" which has a value of (2, or 4 or 5).
Question:
How can I create a query base on my "idcategory" and add the value in my field "subtotals"?
Like:
From Where ID="idcategory" add array??? "not sure really" "subtotal" = Total
To cut it short, I would like to create a simple script where I can add the subtotals from my fields..
Thanks in advance.
Like what Vijay said i think you are looking for an UPDATE.
UPDATE `tblreqslipdetails` SET `subtotals`=`subtotals`+2000 WHERE `idcategory`=2
So I have a 625 digit long number to store in MySQL containing only 0 1 and 2 digits. The best way I've found to store it so far is as VARCHAR(625). I suspect that there are better ways to do it, I'm just not sure how.
I want to run a query such as "change the 128th character of the text to 1" without having to query the text into PHP, change it from there, and write the new text into the DB.
So the question is: what's the simplest method of doing this, and what field type is optimal for this kind of stuff?
Thanks in advance.
If you're going to be doing things like "change the 128th character of the text to 1" then I'd recommend keeping the data type as VARCHAR(625). If the length will always be 625 then you could use CHAR.
This will change the 128th character to 1 in MySQL:
UPDATE your_table set your_column =
CONCAT(SUBSTRING(your_column, 1, 127), '1', SUBSTRING(your_column, 129))
You can user INSERT() String function
give it a try
UPDATE tbl set field = INSERT(field,128,1,'1') where id = primary key
If you're only storing numbers, why not use int(625) instead of varchar?
You can use a replace command, but you'll have to know what to replace with
update TABLE_NAME set FIELD_NAME = replace(FIELD_NAME, ‘find this string’, ‘replace found string with this string’);
If you don't know what exactly you're replace with, you can replace the "replace found string with this string" with a sub query. Using length and substr to split, replace what you want, and concat back together.
This example should make what I'm saying make more sense
http://sqlfiddle.com/#!2/dbc21/2/0quey
A complex alternative:
Replacing 5th character to 'r' where primary key is 30:
update `myTable` set `myField`= regexp_replace(`myField`, '.', 'r', 5, 1) where `id`=30 limit 1