PHP Mysql update set replace exact match - php

I need help replacing exact numbers in my database.
My table look likes this..
ID NAME IMAGES
-------------------------------
1 person1 1,2,3...101,102,103
When I use
mysql_query("UPDATE table SET images = REPLACE(images, '3,', '') WHERE id = '1'");
It removes all the 3 from all numbers that end with 3..
13, = 1
23, = 2
113, = 11

As has been mentioned already, the correct solution is to normalize the data. However if you are stuck with this table structure, you can still perform a single UPDATE statement using 3 CASE conditions to match the number at the beginning, middle, or end.
To remove it from the beginning or end of the list, you may use a SUBSTR(), and continue using REPLACE() to remove it from the middle of the list.
UPDATE
table
SET images =
CASE
/* if 3 is in the leftmost position in the list, remove first 2 chars... */
WHEN LEFT(images, 2) = '3,' THEN SUBSTR(images, 3)
/* if 3 is in the rightmost position in the list, remove last 2 chars... */
WHEN RIGHT(images, 2) = ',3' THEN SUBSTR(images, 1, LENGTH(images) - 2)
/* Otherwise replace a single 3 bounded by commas with a single comma */
ELSE REPLACE(images, ',3,', ',')
END
WHERE id = '1'

Related

Perform an exact match SQL database query with PHP against a list of values in a database column

I'm working with a SQL Database
My database has a column with the "Term" and a column with the "Content"
Right now when I get a user input for the "Term", I query the database using that term to get the term's content.
Is it possible to have a comma separated list of terms in the "Term" column and if the user's term is in the list of terms, then it returns that term's content?
Here is my SQL Database as a PHP array:
$database = array(
0 => array("term" => "example", "content" => "example content"),
1 => array("term" => "example, examples, many examples", "content" => "example content"),
);
Right now I can only return the row with index 0. I want to be able to return row 1 if the user's term is an exact match of one of the items in the list, in this case "example", "examples", or "many examples".
<?php
$sql_query = $connection->prepare("SELECT *
FROM database WHERE term LIKE :term
ORDER BY priority DESC
LIMIT 10");
$term = "example";
$sql_query->bindParam(":term", $term );
$sql_query->execute();
$result = $sql_query->fetchAll(); // Gets all results and turns them into an array
?>
Is it possible for me to perform a database query that compares the user's "Term" to the comma separated list of "Terms"? Keep in mind they have to be exact matches.
use this
WHERE FIND_IN_SET(:term, term)
Use regular expression(regexp) for word match and BINARY for case sensitivity.
SELECT *
FROM database
WHERE term REGEXP BINARY '[[:<:]]:term[[:>:]]'
ORDER BY priority DESC
LIMIT 10
Regexp is kinda the same as preg_match in php, it looks for match by pattern.
[[:<:]], [[:>:]] These markers stand for word boundaries. They match
the beginning and end of words, respectively. A word is a sequence of
word characters that is not preceded by or followed by word
characters. A word character is an alphanumeric character in the alnum
class or an underscore (_).

PHP: Separate Area Code from Phone number with MySQL Database

I want to separate the area code from a phone number string by using a area code mysql database.
For example the string is 0349152023.
The endresult should be 03491 52023.
To get the endresult, i want to split the string and search every digit in database.
For example 0 and then 3 and then 4 and then take the last found result.
The code i have at the moment is only to prepare the phone number string for futher actions:
$phone1 = preg_replace('/[oO]/', '0', $phone-string);
$phone2 = preg_replace("/[^0-9]/", "", $phone1);
Then i use str_split to cut the string in pieces:
$searchArray = str_split($phone2);
Thanks for your help.
You may build an array containing all the area codes.
Then you may write something like this:
foreach ($area_codes as $code) {
if (substr($phone, 0, strlen($code)) == $code) {
$phone_string = substr($phone, 0, strlen($code))." ".substr($phone, strlen($code));
}
}
You can obviously add a controller in order to verify if the area code was found or not.
step 1: select all area codes from db and put them into an array $areaCodes
step 2: iterate over $areaCodes as $code and check if the phonenumber starts with $code. if it does, create a string that has a whitespace between the code and the rest of the number
$phonenumber = '0349152023';
$preparedPhonenumber = '';
foreach($areaCodes as $code){
if(str_pos($phonenumber, $code) === 0){
// phonenumber starts with areacode
$phoneWithoutCode = substr($phonenumber, strlen($code));
$preparedPhonenumber = $code.' '.$phoneWithoutCode;
break;
}
}
// if one of the areaCodes was 0349,
// the variable $preparedPhonenumber is now '0349 152023'
edit: you can shorten the amount of returned area codes from db by selecting only those that start with a certain string.
Let's assume the shortest area code in germany is 3 digits long (which i think is correct).
$threeDigits = substr($phonenumber,0,3);
$query = "SELECT * from areacodes
WHERE code like '".$threeDigits."%'
ORDER BY CHAR_LENGTH(code) DESC";
this will drastically shrink down the probable area codes array, therefore making the script faster.
edit 2: added order by clause in query so the above code will check for longer areacodes first. (the break; in the foreach loop is now obligatory!)
Hi Leonardo Gugliotti and Cashbee
i sort the areaCodes to get a better match. The php scripts works fine, but takes to long time to handle 5000 MySQL entries. Is it possible to make the foreach search directly in mySQL?
<?php
$sample_area_codes = array( '0350', '034', '034915', '03491', '0348', '0349', '03491', '034916', '034917',);
sort($sample_area_codes);
$phone_string = '0349152023';
foreach ($sample_area_codes as $code) {
$subString = substr($phone_string, 0, strlen($code));
if ($subString == $code) {
$phone = $subString." ".substr($phone_string, strlen($code));
}
}
if (!empty($phone)) {
echo $phone;
}
else {
echo "No AreaCode found.";
}
?>
Output: 034915 2023, which is correct
A single probe (assuming INDEX(area_code)):
SELECT ...
FROM AreaCodes
WHERE area_code < ?
ORDER BY area_code DESC
LIMIT 1;
(Where you bind the $phone_number as a string into the ?)
I think you'd better split your database into a tree, making a table for each digit.
So the third digit could refer to the second, the fourth to the third, and so on until you reach the maximum lenght of the prefix. The last table should include the name of the area.
Following your example, supposing that the maximum lenght of the area code was five digits, the fifth_digit_table should have at least four fields like these:
ID
IDref
Number
Name
10 records may have the same IDref, corresponding to the number "2" at the fourth position, linked to the previous "021" through the fourth_digit_table, the three_digit_table and so on; only one among these records, that with the Number field filled with "9", should have the Name "Haan"; the others, if there aren't any, should have the Name "Solingen".
I hope you will manage to speed up your script.

Adding an integer value into string in laravel

Hello Every one,
I have an issue that is, I want to add an integer into a string for example I have two text field one is called series start and the other one is called series end now if user enters
FAHD1000001 into series start field
AND
FAHD1000100 into series end field
the algorithm should store 100 values into the database with increment into the each entry that is going to store into the database. i.e
FAHD1000001, FAHD1000002, FAHD1000003, ........., FAHD1000100
Is it possible to do so, if yes then how. Please help me
You have to do something like this but there is a loop hole if you have any numeric value in name like F1AHD00001 than it will not work
$str1 = $request['start'];
$str2 = $request['end'];
$startint=preg_replace("/[^0-9]/","",$str1);
$endint=preg_replace("/[^0-9]/","",$str2 );
$words = preg_replace('/[[:digit:]]/', '', $str1);
for($i=$startint;$i<$endint;$i++){
$newstring=$words.$i;
//Save this new String
}

Create an ID based on integer with letter

I have a database containing messages with an "id" column in integer auto increment. Classical. But I would like to create a "visual" id based on this integer id. This is what I want :
A0001
A0002
[...]
A9999
B0001
B0002
[etc]
The ideal would be to generate automatically (in MYSQL) this messageId based on the integer id. I can also generate this id in PHP. But how ? The difficulty is that we have to check the last id in database to calculate what letter prefix the visual id.
Can you help me to generate this ? In MYSQL if it possible directly or in PHP?
You could use the following, but it is only good for numbers from 0 to 249999 (A0000 - Z9999)
select concat(char(ord('A')+round(ID / 10000)),ID % 10000) from ...
To convert back from a visual ID you can use the following:
select ord(VISUAL_ID)-ord('A')+mid(VISUAL_ID,2)
have you considered using hex? Why not to write OxA001 it's still integer if you do A001 then it's string and no AUTO INCREMENT is possible.
But if you want really to do it in mysql the only way would be using TRIGGERS.
You have 2 options you can create insert AFTER or BEFORE Insert statement and in this trigger you should update the value of ID to your value based on previous row. But I really recomend using hex.
You can read more about triggers here
You can create such ids using a before insert trigger to create the new value.
Basically you would look up the maximum value and then increment it, by doing something like:
(case when maxvalue like '%9999'
then concat(char(ascii(left(maxvalue, 1) + 1)), '0000')
else concat(left(maxvalue, 1), lpad(right(maxvalue, 4) + 1), 4, '0')
end);
However, I would discourage you from doing this and just set up a regular auto-increment column.
try this it may help you.
for ($i = 'A'; $i != 'AA'; $i++)
{
$prefix = $i;
$id = $prefix.sprintf("%03s",$suffix);
for ($j=1;$j<=5;$j++)
{
$res = "$id"."$j";
echo "$res"."<br>";
}
}

Remove values in comma separated list from database

I have a table in my MySQL database called 'children'. In that table is a row called 'wishes' (a comma separated list of the child's wishlist items). I need to be able to update that list so that it only removes one value. i.e. the list = Size 12 regular jeans, Surfboard, Red Sox Baseball Cap; I want to remove Surfboard.
My query right now looks like this
$select = mysql_query('SELECT * FROM children WHERE caseNumber="'.$caseNum.'" LIMIT 1 ');
$row = mysql_fetch_array($select);
foreach ($wish as $w) {
$allWishes = $row['wishes'];
$newWishes = str_replace($w, '', $allWishes);
$update = mysql_query("UPDATE children SET wishes='$newWishes' WHERE caseNum='".$caseNum."'");
}
But the UPDATE query isn't removing anything. How can I do what I need?
Using these user-defined REGEXP_REPLACE() functions, you may be able to replace it with an empty string:
UPDATE children SET wishes = REGEXP_REPLACE(wishes, '(,(\s)?)?Surfboard', '') WHERE caseNum='whatever';
Unfortunately, you cannot just use plain old REPLACE() because you don't know where in the string 'Surfboard' appears. In fact, the regex above would probably need additional tweaking if 'Surfboard' occurs at the beginning or end.
Perhaps you could trim off leading and trailing commas left over like this:
UPDATE children SET wishes = TRIM(BOTH ',' FROM REGEXP_REPLACE(wishes, '(,(\s)?)?Surfboard', '')) WHERE caseNum='whatever';
So what's going on here? The regex removes 'Surfboard' plus an optional comma & space before it. Then the surrounding TRIM() function eliminates a possible leading comma in case 'Surfboard' occurred at the beginning of the string. That could probably be handled by the regex as well, but frankly, I'm too tired to puzzle it out.
Note, I've never used these myself and cannot vouch for their effectiveness or robustness, but it is a place to start. And, as others are mentioning in the comments, you really should have these in a normalized wishlist table, rather than as a comma-separated string.
Update
Thinking about this more, I'm more partial to just forcing the use of built-in REPLACE() and then cleaning out the extra comma where you may get two commas in a row. This is looking for two commas side by side, as though there had been no spaces separating your original list items. If the items had been separated by commas and spaces, change ',,' to ', ,' in the outer REPLACE() call.
UPDATE children SET wishes = TRIM(BOTH ',' FROM REPLACE(REPLACE(wishes, 'Surfboard', ''), ',,', ',')) WHERE caseNum='whatever';
Not exactly a direct answer to your question, but like Daren says it's be better having wishes as its own table. Maybe you could change your database schema so you have 3 tables, for instance:
children
-> caseNum
-> childName
wishes
-> caseNum
-> wishId
-> wishName
childrensWishes
-> caseNum
-> wishId
Then to add or delete a wish for a child, you just add or delete the relevant row from childrensWishes. Your current design makes it difficult to manipulate (as you're finding), plus leaves you at risk for inconsistent data.
As a more direct answer, you could fix your current way by getting the list of wishes, explode() 'ing them, removing the one you don't want from the array and implode() 'ing it back to a string to update the database.
Make wishes table have this format:
caseNumber,wish
Then you get all of a child's wishes like this:
SELECT * FROM children c left join wishes w on c.caseNumber = w.caseNumber WHERE c.caseNumber= ?
Removing a wish becomes:
DELETE from wishes where caseNumber = ?
Adding a wish becomes:
INSERT into wishes (caseNumber,wish) values (?,?)
Returning one wish becomes:
SELECT * FROM children c left join wishes w on c.caseNumber = w.caseNumber WHERE c.caseNumber= ? LIMIT 1
Having the wishes indexed in an array which is thereafter serialized could be an idea, otherwise you would need to retrieve the string, slice it, remove the part you don't want, then concatenate the remains. This can be done by using the explode() function.
If you were to use an array, you would retrieve the array and then sort through it with a loop like this:
// Wishes array:
// Array (
// [0] Regular Jeans
// [1] Surfboard
// [2] Red Sox Baseball Cap
// )
$wishes = $row['wishes']; // This is a serialized array taken from the database
$wishes = unserialize($wishes);
foreach ($wishes as $key => $value) {
if ($value == 'Surfboard') {
unset($wishes[$key]);
break;
}
}
$wishes = serialize($wishes);
// Update database
Keep in mind that index [1] now won't exist in the array, so if you wish to have a clean array you should loop through the array and make it create a new array by itself:
foreach ($wishes as $wishes) {
$newArray[] = $wishes;
}
I think the best answer to such issue is here
The best way to remove value from SET field?
query should be like this which covers the ,value or value, or only value in the comma separated column
UPDATE yourtable
SET
categories =
TRIM(BOTH ',' FROM
REPLACE(
REPLACE(CONCAT(',',REPLACE(col, ',', ',,'), ','),',2,', ''), ',,', ',')
)
WHERE
FIND_IN_SET('2', categories)
Here you can have your condition in where clause. for more details refer above link.
You can create function like this:
CREATE FUNCTION `remove_from_set`(v int,lst longtext) RETURNS longtext CHARSET utf8
BEGIN
set #lst=REPLACE(#lst, ',,', ',');
set #lng=LENGTH(#lst) - LENGTH(REPLACE(#lst, ',', ''))+1;
set #p=find_in_set(#v,#lst);
set #l=SUBSTRING_INDEX( #lst, ',', #p-1);
set #r=SUBSTRING_INDEX( #lst, ',', #p-#lng);
IF #l!='' AND #r!='' THEN
return CONCAT(#l,',',#r);
ELSE
RETURN CONCAT(#l,'',#r);
END IF;
END
Using:
SELECT remove_from_set('1,,2,3,4,5,6',1)

Categories