I would like to return the first letter of each word in a MySQL column called 'initials'.
For example, my table may look like this:
| project_unit | initials |
+---------------------------------------+----------+
| Mbita Clinic Rehabilitation | MCR |
| Management Strategy for Thrips Cowpea | MSTC |
Any suggestions?
You can use below mentioned function to achieve your requirement.
DELIMITER $$
CREATE FUNCTION split_string(split_string varchar(255),my_delimiter varchar(1)) RETURNS varchar(10)
BEGIN
DECLARE temp_string varchar(255);
DECLARE occurance INT;
DECLARE i INT;
DECLARE temp_result varchar(10);
DECLARE final_result varchar(10);
SET temp_result = '';
SET occurance=length(split_string)-length(replace(split_string,' ',''))+1;
IF occurance > 0 then
set i=1;
while i <= occurance do
set temp_string = (select SUBSTRING_INDEX(SUBSTRING_INDEX(split_string, my_delimiter, i),my_delimiter ,-1));
set temp_result = CONCAT(temp_result, SUBSTRING(temp_string,1,1));
set i=i+1;
end while;
ELSE
set temp_result = SUBSTRING(split_string,1,1);
END IF;
set occurance=0;
SET final_result = temp_result;
RETURN (final_result);
END $$
DELIMITER ;
You can use it like this :
SELECT Projcect_unit, split_string(Projcect_unit,' ') as initials FROM main_table;
Since MySQL does not support Regex replacement, you will need to first include UDF (User Defined Function) which you can get from this link.
Once you have the regexp_replace function, you can simply use
select regexp_replace('Mbita Clinic Rehabilitation', '[a-z ]', '')
which would return MRC.
Note that the current regex will remove lowercase letter and spaces, but if your field can contains number or any other character you will have to modify the regex.
Hope this helped.
MySql does not provide such try string operation function so you need create function and call function with query
DELIMITER $$
CREATE FUNCTION `GetUpperCase`(InputString VARCHAR(1024)) RETURNS varchar(1024) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE return_string,inputDATA VARCHAR(1024);
DECLARE schar VARCHAR(1);
DECLARE string_length, char_code INT;
SET string_length = LENGTH(InputString);
SET inputDATA = InputString ;
SET return_string = '';
WHILE string_length > 0 DO
SET schar = SUBSTRING(inputDATA FROM (-1 * string_length) FOR 1);
SET char_code = ORD(schar);
IF char_code >= 65 AND char_code <= 90 THEN
SET return_string = CONCAT(return_string, schar);
END IF;
SET string_length = string_length - 1;
END WHILE;
RETURN return_string;
END $$
DELIMITER ;
and call function with SQL select query
mysql> SELECT GetUpperCase("Mbita Clinic Rehabilitation Management Strategy for Thrips Cowpea") AS `initials`;
+----------+
| initials |
+----------+
| MCRMSTC |
+----------+
Related
delimiter $$
create procedure increase_charge()
begin
declare v_name VARCHAR(120);
declare v_oldchg VARCHAR(120);
declare v_newchg VARCHAR(120);
declare not_found int default 0;
declare c_nur cursor for select n_name,n_charge
from Nurses
Where n_charge < 70;
declare continue handler for not found set not_found = 1;
open c_nur;
loop_label:
loop
fetch c_nur into v_name,v_oldchg;
if not_found = 1 then LEAVE loop_label; END IF;
set v_newchg= v_oldchg+( v_oldchg*0.20);
UPDATE Nurses
SET n_charge = v_newchg
WHERE Nurses.n_name = v_name;
SELECT'Nurse name',ifnull(v_name, '');
SELECT'Old change per hour',ifnull(v_oldchg, '');
SELECT'New charge per hour',ifnull(v_newchg, '');
end loop;
close c_nur;
end;
delimiter;
call increase_charge;
There is nothing wrong with your code and it works as expected with the minor syntax corrections.
drop table if exists nurses;
create table nurses(n_name varchar(3),n_charge int);
insert into nurses values('aaa',10),('bbb',80);
drop procedure if exists increase_charge;
delimiter $$
create procedure increase_charge()
begin
declare v_name VARCHAR(120);
declare v_oldchg VARCHAR(120);
declare v_newchg VARCHAR(120);
declare not_found int default 0;
declare c_nur cursor for select n_name,n_charge
from Nurses
Where n_charge < 70;
declare continue handler for not found set not_found = 1;
open c_nur;
loop_label:
loop
fetch c_nur into v_name,v_oldchg;
if not_found = 1 then LEAVE loop_label; END IF;
set v_newchg= v_oldchg+( v_oldchg*0.20);
UPDATE Nurses
SET n_charge = v_newchg
WHERE Nurses.n_name = v_name;
SELECT'Nurse name',ifnull(v_name, '');
SELECT'Old change per hour',ifnull(v_oldchg, '');
SELECT'New charge per hour',ifnull(v_newchg, '');
end loop;
close c_nur;
end $$
delimiter ;
call increase_charge();
select * from nurses;
+--------+----------+
| n_name | n_charge |
+--------+----------+
| aaa | 12 |
| bbb | 80 |
+--------+----------+
2 rows in set (0.001 sec)
BTW this can be done with a simple update statement
update nurses
set n_charge = n_charge + (n_charge * .2)
where n_charge < 70;
I'm looking to do some validation of data replication between some different database systems, with different character sets (potentially) and a third party software that migrates the data. To help test an aspect of this, I'm looking to do something like the following.
ASCII(foo) returns the value for the first character in the string. Is there a way to get the ascii values for all characters in a string in one go, in one select statement? Something like concating the values together, separated by a space. E.g. If the string was hello then the output would be 104 101 108 108 111
Reference:
select ascii('h'); -- 104
select ascii('e'); -- 101
select ascii('l'); -- 108
select ascii('o'); -- 111
Just had the same problem, so here is a procedure that does the work:
DELIMITER $$
CREATE PROCEDURE string_to_ascii(IN inputStr VARCHAR(255))
BEGIN
DECLARE strLen INT DEFAULT 0;
DECLARE idx INT DEFAULT 0;
DECLARE current_char VARCHAR(1);
DECLARE current_char_ascii VARCHAR(10);
DECLARE outputStr TEXT;
IF inputStr IS NULL THEN
SET inputStr = '';
END IF;
SET strLen = CHAR_LENGTH(inputStr);
SET idx = 1;
WHILE idx <= strLen DO
SET current_char = SUBSTR(inputStr, idx, 1);
SET current_char_ascii = ASCII(current_char);
IF idx = 1 THEN
SET outputStr = current_char_ascii;
ELSE
SET outputStr = CONCAT(outputStr, ",", current_char_ascii);
END IF;
SET idx = idx+1;
END WHILE;
SELECT outputStr;
END
$$
DELIMITER ;
Usage:
> CALL string_to_ascii('hello');
+---------------------+
| outputStr |
+---------------------+
| 104,101,108,108,111 |
+---------------------+
If you prefer to use it as a function:
DELIMITER //
CREATE FUNCTION string_to_ascii ( inputStr TEXT )
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE strLen INT DEFAULT 0;
DECLARE idx INT DEFAULT 0;
DECLARE current_char VARCHAR(1);
DECLARE current_char_ascii VARCHAR(10);
DECLARE outputStr TEXT;
IF inputStr IS NULL THEN
SET inputStr = '';
END IF;
SET strLen = CHAR_LENGTH(inputStr);
SET idx = 1;
WHILE idx <= strLen DO
SET current_char = SUBSTR(inputStr, idx, 1);
SET current_char_ascii = ASCII(current_char);
IF idx = 1 THEN
SET outputStr = current_char_ascii;
ELSE
SET outputStr = CONCAT(outputStr, ",", current_char_ascii);
END IF;
SET idx = idx+1;
END WHILE;
RETURN outputStr;
END; //
DELIMITER ;
And then the usage will be:
> SELECT string_to_ascii('hello');
+--------------------------+
| string_to_ascii('hello') |
+--------------------------+
| 104,101,108,108,111 |
+--------------------------+
I have a field text, In it there is information about such
sch hcbhsc hscbshcbc xxxxxxxx sgxfag jdhajdh;
dchbdbc bdcbdh bchdbd xx/xx-xxxx/xx svdhs sbjbsc
bdchbdc jncjdnc jbcjb xx/xx-xxxxx/xx gcvsgc jcbjsb
dchjbd bhjcbdcb bdcbcd xx-xxxx/xx shchscv hscbhsc
dhcbhd jdcbjdb jdcnjdcn xx-xxxxx/xx shcvsch jbscjc
Place x is only a digit, I need to write select and only those numbers are taken
Use SUBSTRING and PATINDEX string functions IN SQL server :
SELECT SUBSTRING(Your_FieldName, PATINDEX('%[0-9]%', Your_FieldName),
LEN(Your_FieldName))
For MYSQL refer below URL :
Query to get only numbers from a string
string
There is no formal PATINDEX() function in MySQL that achieves both the regex pattern lookup with returned character index, define User-Defined function that loops through each character in the length of a string and checks a REGEXP pattern on the character. Once created, use such a function in-line of a query.
DROP FUNCTION IF EXISTS PatIndex;
DELIMITER $$
CREATE FUNCTION PatIndex(pattern VARCHAR(255), tblString VARCHAR(255)) RETURNS INTEGER
DETERMINISTIC
BEGIN
DECLARE i INTEGER;
SET i = 1;
myloop: WHILE (i <= LENGTH(tblString)) DO
IF SUBSTRING(tblString, i, 1) REGEXP pattern THEN
RETURN(i);
LEAVE myloop;
END IF;
SET i = i + 1;
END WHILE;
RETURN(0);
END
Here is a MySQL function (routine) that will do just that. It is an improved version from the solution given here: how-to-get-only-digits-from-string-in-mysql
This improved version can handle much larger numbers. The old solution was limited by the INTEGER value, so if you had phone numbers for example (or string containing many digits), it would fail with out of range for column.
DELIMITER $$
CREATE FUNCTION ExtractNumber (in_string VARCHAR(50))
RETURNS varchar(50)
NO SQL
BEGIN
DECLARE ctrNumber VARCHAR(50);
DECLARE finNumber VARCHAR(50) DEFAULT '';
DECLARE sChar VARCHAR(1);
DECLARE inti VARCHAR(50) DEFAULT 1;
IF LENGTH(in_string) > 0 THEN
WHILE(inti <= LENGTH(in_string)) DO
SET sChar = SUBSTRING(in_string, inti, 1);
SET ctrNumber = FIND_IN_SET(sChar, '0,1,2,3,4,5,6,7,8,9');
IF ctrNumber > 0 THEN
SET finNumber = CONCAT(finNumber, sChar);
END IF;
SET inti = inti + 1;
END WHILE;
RETURN CAST(finNumber AS UNSIGNED);
ELSE
RETURN 0;
END IF;
END$$
DELIMITER ;
Now you can do this:
SELECT ExtractNumber(my_field)
FROM my_table;
I'm learning stored procedures/functions/triggers in MySQL this morning and I'm having some problems trying to use variable table and column names in queries.
DELIMITER |
USE R2R |
DROP FUNCTION IF EXISTS getCategoryName |
CREATE FUNCTION getCategoryName(LMID INT, levelNum INT)
RETURNS VARCHAR(255)
BEGIN
DECLARE levelName VARCHAR(255) DEFAULT makeLevelName(levelNum);
DECLARE levelID INT;
DECLARE levelNameID VARCHAR(255) DEFAULT CONCAT(levelName, 'ID');
DECLARE ret VARCHAR(255);
SELECT #levelNameID INTO levelID FROM LevelMaster WHERE id=LMID;
SELECT description INTO ret FROM #levelName WHERE id=levelID;
RETURN ret;
END;
|
DROP FUNCTION IF EXISTS makeLevelName |
CREATE FUNCTION makeLevelName(levelNum INT)
RETURNS VARCHAR(255)
BEGIN
DECLARE word VARCHAR(255);
DECLARE ret VARCHAR(255);
IF levelNum=2 THEN SET word='Two';
ELSEIF levelNum=3 THEN SET word='Three';
ELSEIF levelNum=4 THEN SET word='Four';
ELSEIF levelNum=5 THEN SET word='Five';
END IF;
SET ret=CONCAT('Level', word);
RETURN ret;
END;
|
SELECT getCategoryName(347, 2) |
It's the first function (getCategoryName) that's causing me the problems, I need the two variables marked with # to be the table/column names - these two lines:
SELECT #levelNameID INTO levelID FROM LevelMaster WHERE id=LMID;
SELECT description INTO ret FROM #levelName WHERE id=levelID;
I want to keep this function as a function rather than a procedure if possible, but would accept answers for a procedure if it's the only way.
Thanks for you help,
Richard
Use User/Global Vars for this along with PREPARE & EXECUTE:
SET #columnName='myColumn';
SET #tableName='myTable';
SET #whatEver='requiredValue';
SET #query=CONCAT('SELECT ', #columnName, ' FROM ', #tableName, ' WHERE Column=', #whatEver);
PREPARE QUERY FROM #QUERY;
EXECUTE QUERY;
Haven't tested this EXACT code but something along these lines will work. Also has to be inside a Procedure, cannot be used with a function or trigger, if anyone has a soloution for that then please post.
In MySQL, I have this stored procedure with a LOOP:
DELIMITER $$
CREATE PROCEDURE ABC()
BEGIN
DECLARE a INT Default 0 ;
simple_loop: LOOP
SET a=a+1;
select a;
IF a=5 THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
END $$
It always prints 1. What is the correct syntax for a MySQL Loop?
drop table if exists foo;
create table foo
(
id int unsigned not null auto_increment primary key,
val smallint unsigned not null default 0
)
engine=innodb;
drop procedure if exists load_foo_test_data;
delimiter #
create procedure load_foo_test_data()
begin
declare v_max int unsigned default 1000;
declare v_counter int unsigned default 0;
truncate table foo;
start transaction;
while v_counter < v_max do
insert into foo (val) values ( floor(0 + (rand() * 65535)) );
set v_counter=v_counter+1;
end while;
commit;
end #
delimiter ;
call load_foo_test_data();
select * from foo order by id;
While loop syntax example in MySQL:
delimiter //
CREATE procedure yourdatabase.while_example()
wholeblock:BEGIN
declare str VARCHAR(255) default '';
declare x INT default 0;
SET x = 1;
WHILE x <= 5 DO
SET str = CONCAT(str,x,',');
SET x = x + 1;
END WHILE;
select str;
END//
Which prints:
mysql> call while_example();
+------------+
| str |
+------------+
| 1,2,3,4,5, |
+------------+
REPEAT loop syntax example in MySQL:
delimiter //
CREATE procedure yourdb.repeat_loop_example()
wholeblock:BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = 5;
SET str = '';
REPEAT
SET str = CONCAT(str,x,',');
SET x = x - 1;
UNTIL x <= 0
END REPEAT;
SELECT str;
END//
Which prints:
mysql> call repeat_loop_example();
+------------+
| str |
+------------+
| 5,4,3,2,1, |
+------------+
FOR loop syntax example in MySQL:
delimiter //
CREATE procedure yourdatabase.for_loop_example()
wholeblock:BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = -5;
SET str = '';
loop_label: LOOP
IF x > 0 THEN
LEAVE loop_label;
END IF;
SET str = CONCAT(str,x,',');
SET x = x + 1;
ITERATE loop_label;
END LOOP;
SELECT str;
END//
Which prints:
mysql> call for_loop_example();
+-------------------+
| str |
+-------------------+
| -5,-4,-3,-2,-1,0, |
+-------------------+
1 row in set (0.00 sec)
Do the tutorial: http://www.mysqltutorial.org/stored-procedures-loop.aspx
If I catch you pushing this kind of MySQL for-loop constructs into production, I'm going to shoot you with the foam missile launcher. You can use a pipe wrench to bang in a nail, but doing so makes you look silly.
Assume you have one table with name 'table1'. It contain one column 'col1' with varchar type. Query to crate table is give below
CREATE TABLE `table1` (
`col1` VARCHAR(50) NULL DEFAULT NULL
)
Now if you want to insert number from 1 to 50 in that table then use following stored procedure
DELIMITER $$
CREATE PROCEDURE ABC()
BEGIN
DECLARE a INT Default 1 ;
simple_loop: LOOP
insert into table1 values(a);
SET a=a+1;
IF a=51 THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
END $$
To call that stored procedure use
CALL `ABC`()
You can exchange this local variable for a global, it would be easier.
DROP PROCEDURE IF EXISTS ABC;
DELIMITER $$
CREATE PROCEDURE ABC()
BEGIN
SET #a = 0;
simple_loop: LOOP
SET #a=#a+1;
select #a;
IF #a=5 THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
END $$