is there anything like substr_replace in MySQL? - mysql

I have column data that looks like this "132154646878"
And i would like replace a part of each one from a specified position
something like :
substr_replace("132154646878","***",4)
Output => 132***646878
Any functions in MySQL?

Looks like you are looking for MySQL's INSERT function.
INSERT(str, pos, len, newstr)
Returns the string str, with the substring beginning at position pos
and len characters long replaced by the string newstr. Returns the
original string if pos is not within the length of the string.
Replaces the rest of the string from position pos if len is not within
the length of the rest of the string. Returns NULL if any argument is
NULL.
source https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_insert
Query
SELECT INSERT("132154646878", 4, LENGTH('***'), "***");
p.s keep in mind that when you use multibyte characters charset like utf8 in the newstr parameter you need to use CHAR_LENGTH() instead off LENGTH()
Result
| INSERT("132154646878", 4, LENGTH('***'), "***") |
| ----------------------------------------------- |
| 132***646878 |
View on DB Fiddle

Related

Convert string -> binary -> integer in snowflake

I am attempting to convert a string to its binary representation and ultimately an integer in Snowflake, but am unable to get the desired result with either TO_BINARY or ::BINARY(<n>). For example, I am able to do what I want in postgres with the following code
SELECT ('x' || 'abcd')::BIT(32)
which returns 10101011110011010000000000000000 as desired.
I want to get the same result in Snowflake, but can't. I have tried both of the following, but simply get the same string returned (e.g. ABCD returned as output)
SELECT TO_BINARY('abcd')
...
SELECT 'abcd'::BINARY(32)
I am attempting to convert a string to its binary representation and
ultimately an integer in Snowflake
If you need to convert a hex value to integer in Snowflake, it's easy:
select TO_NUMBER( 'abcd', 'XXXX' );
43981
If you need to convert a hex value to bits, Snowflake does not have a native function but it's possible to write a JavaScript function:
create or replace function convert_to_bits( decimal_value float, size float )
returns string
language javascript
as $$
var res = parseInt(DECIMAL_VALUE).toString(2);
return res + "0".repeat( SIZE - res.length );
$$;
select convert_to_bits(TO_NUMBER( 'abcd', 'XXXX' ), 32) ;
10101011110011010000000000000000

Find a string in a MySQL field with concurrences

Is there any function in MySQL where I especifies the concurrences numbers for the search?
Example:
lcString = "My name-is-Harry-Potter"
In Visual FoxPro you can use this:
?AT('a',lcString,1) && where 1 means "get me the first concurrence"
OutPut = 5
Or
?AT('-',lcString,3) && where 3 means "get me the third concurrence"
OutPut = 17
I was looking for a similar function in mysql but I can't find it.
Thank you all...!!!
You can use SUBSTRING_INDEX and LENGTH MySQL functions to achieve that. This is what MySQL's documentation says about SUBSTRING_INDEX:
Returns the substring from string str before count occurrences of the
delimiter
So, you can wrap that inside LENGTH to get the occurrence, e.g.:
SELECT LENGTH(SUBSTRING_INDEX('My name-is-Harry-Potter', 'a', 1)) + 1
SELECT LENGTH(SUBSTRING_INDEX('My name-is-Harry-Potter', '-', 3)) + 1

Mysql - How to do a case sensitive search?

I have 4cci and 4ccI values in database. When I run this query I get both rows.
select * from urls where url = "4cci";
How to do a case sensitive search?
Depend on your text field collation
Check the manual
mysql> SET #s1 = 'MySQL' COLLATE latin1_bin,
-> #s2 = 'mysql' COLLATE latin1_bin;
mysql> SELECT #s1 = #s2;
+-----------+
| #s1 = #s2 |
+-----------+
| 0 |
+-----------+
Use keyword BINARY before the column you want to perform case sensitive search
Description :
The BINARY function converts a value to a binary string.
Example
Suppose we have one table stores with 3 records where two recoard have country column as "IN" and one has as "in"
select count(*) from stores where BINARY country = 'in';
Output : count : 1
OR
Use CAST() function :
Description :
Convert a value to a DATE datatype:
select count(*) from stores where CAST(country AS BINARY) = 'IN';
Output : count : 2
How these function works :
Understand with simple example :
SELECT BINARY "HELLO" = "hello";
Output : 0
Here MySQL performs a byte-by-byte comparison of "HELLO" and "hello" and return 0 (because on a byte-by-byte basis, they are NOT equivalent):

Selecting multiple substrings from a field in MySQL

I have a field that is a longtext in MySQL. I'm looking for any instances of 'media' that could be in it, +/- ~10 characters of context. There are usually multiple instances in a single rows' field, so I need to see the context. How can I write a query to do this? I can't even think of where to start.
So what I'm looking at is this:
SELECT field_data_body FROM table WHERE field_data_body LIKE '%media%';
+----------------------------------+
| field_data_body |
+----------------------------------+
| ... ode__media_or ... e immediat |
+----------------------------------+
The field is actually a long string, and I just parsed the actual test value to show the substrings that would match the WHERE clause.
What I actually want to see is all instances of the string media, which in the example above is two, but in other fields could be more. SUBSTR only shows the first instance of media.
CREATE FUNCTION of your own. Inside the function you can use the WHILE statement and general string functions such as LOCATE and SUBSTRING.
Here is an example to get you started:
DELIMITER $$
CREATE FUNCTION substring_list(
haystack TEXT,
needle VARCHAR(100)
)
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE needle_len INT DEFAULT CHAR_LENGTH(needle);
DECLARE output_str TEXT DEFAULT '';
DECLARE needle_pos INT DEFAULT LOCATE(needle, haystack);
WHILE needle_pos > 0 DO
SET output_str = CONCAT(output_str, SUBSTRING(haystack, GREATEST(needle_pos - 10, 1), LEAST(needle_pos - 1, 10) + needle_len + 10), '\n');
SET needle_pos = LOCATE(needle, haystack, needle_pos + needle_len);
END WHILE;
RETURN output_str;
END$$
DELIMITER ;
Here are some tests. For each match, the term ("media") and up to 10 characters on either side are returned, all concatenated in a single string:
SELECT substring_list('1234567890media12345678immediate34567890media1234567890', 'media');
+---------------------------+
| 1234567890media12345678im |
| 12345678immediate34567890 |
| te34567890media1234567890 |
+---------------------------+
SELECT substring_list('0media12345678immediate34567890media1', 'media');
+---------------------------+
| 0media12345678im |
| 12345678immediate34567890 |
| te34567890media1 |
+---------------------------+
In mysql you can create a user define function for this like wordcount. You can get help from this UDF.
mysql count word in sql syntax
Here is a solution using PHP that will return each row and each result plus the surrounding characters in a multidimensional array.
$value = "media";
$surroundingChars = 5;
$strlen = strlen($value);
$stmt = $pdo->prepare("SELECT field_data_body FROM table WHERE field_data_body LIKE ?";
$stmt->execute([ '%'.$value.'%' ]);
$result = 0;
while ($body = $stmt->fetchColumn()) {
$start = 0;
while (($pos = stripos($body, $value, $start)) !== FALSE) {
$return[$result][] = substr($body, $pos - $surroundingChars, $strlen + ($surroundingChars * 2));
// Adjust next start
$start = $pos + $strlen;
}
$result++;
}
You could always change the $return[$result][] line, but to echo all rows in the format you wanted, you could do this:
foreach($return as $row) {
echo implode('..', $row);
}
As you stated in the comments, you'd rather a query, but if you change your mind, here is a solution matching your PHP requirements.

How to find the first number in a text field using a MySQL query?

I like to return only the first number of a text stored in a column of a database table.
User have put in page ranges into a field like 'p.2-5' or 'page 2 to 5' or '2 - 5'.
I am interested in the '2' here.
I tried to
SELECT SUBSTR(the_field, LOCATE('2', the_field, 1)) AS 'the_number'
FROM the_table
and it works. But how to get ANY number?
I tried
SELECT SUBSTR(the_field, LOCATE(REGEXP '[0-9], the_field, 1)) AS 'the_number'
FROM the_table
but this time I get an error.
Any ideas?
Just use REGEXP_SUBSTR():
SELECT REGEXP_SUBSTR(`the_field`,'^[0-9]+') AS `the_number` FROM `the_table`;
Notes:
I'm using MySQL Server v8.0.
This pattern assumes that the_field is trimmed. Otherwise, use TRIM() first.
REGEXP is not a function in MySQL, but something of an operator. Returns 1 if field matches the regular expression, or 0 if it does not. You cannot use it to figure out a position in a string.
Usage:
mysql> SELECT 'Monty!' REGEXP '.*';
-> 1
As for answer to the question: I don't think there is a simple way to do that using MySQL only. You would be better off processing that field in the code, or extract values before inserting.
For the specific case in the question. Where the String is {number}{string}{number}
there is a simple solution to get the first number. In our case we had numbers like 1/2,3
4-10
1,2
and we were looking for the first number in each row.
It turned out that for this case one can use convert function to convert it into number. MySQL will return the first number
select convert(the_field ,SIGNED) as the_first_number from the_table
or more hard core will be
SELECT
the_field,
#num := CONVERT(the_field, SIGNED) AS cast_num,
SUBSTRING(the_field, 1, LOCATE(#num, the_field) + LENGTH(#num) - 1) AS num_part,
SUBSTRING(the_field, LOCATE(#num, the_field) + LENGTH(#num)) AS txt_part
FROM the_table;
This was original post at source by Eamon Daly
What does it do?
#num := CONVERT(the_field, SIGNED) AS cast_num # try to convert it into a number
SUBSTRING(the_field, 1, LOCATE(#num, the_field) + LENGTH(#num) - 1) # gets the number by using the length and the location of #num in field
SUBSTRING(the_field, LOCATE(#num, the_field) + LENGTH(#num)) # finds the rest of the string after the number.
Some thoughts for future use
Its worth keeping another column which will hold the first number after you parsed it before insert it to the database. Actually this is what we are doing these days.
Edit
Just saw that you have text like p.2-5 and etc.. which means the above cannot work as if the string does not start with a number convert return zero
There's no built-in way that I know of, but here's a Mysql function you can define, this will do it (I didn't code for minus-signs or non-integers, but those could of course be added).
Once created, you can use it like any other function:
SELECT firstNumber(the_field) from the_table;
Here's the code:
DELIMITER //
CREATE FUNCTION firstNumber(s TEXT)
RETURNS INTEGER
COMMENT 'Returns the first integer found in a string'
DETERMINISTIC
BEGIN
DECLARE token TEXT DEFAULT '';
DECLARE len INTEGER DEFAULT 0;
DECLARE ind INTEGER DEFAULT 0;
DECLARE thisChar CHAR(1) DEFAULT ' ';
SET len = CHAR_LENGTH(s);
SET ind = 1;
WHILE ind <= len DO
SET thisChar = SUBSTRING(s, ind, 1);
IF (ORD(thisChar) >= 48 AND ORD(thisChar) <= 57) THEN
SET token = CONCAT(token, thisChar);
ELSEIF token <> '' THEN
SET ind = len + 1;
END IF;
SET ind = ind + 1;
END WHILE;
IF token = '' THEN
RETURN 0;
END IF;
RETURN token;
END //
DELIMITER ;