How to use regex in mysql query to remove specific characters? - mysql

In my query I am using REPLACE( b.DESCRIPTION,'SP. Z O.O.','') AS DESCRIPTION to remove SP. Z O.O. these characters from columns. And hopefully it's working for me. But in my database SP. Z O.O. this characters are stored in different ways. Like sp. Z.o.o, SP. z.o.o etc.
Somewhere it's stored in capital letters and somewhere it's stored in small letters.
REPLACE( b.DESCRIPTION,'SP. Z O.O.','') AS DESCRIPTION by this method I am only able to remove capital letters. I want all conditions to remove similar words like this.
How to apply regex or case in this situation?
This is my query:
SELECT b.TRANS_DETAILS_ID, b.CREDIT_AMOUNT, b.ENTITY_NAME, REPLACE( b.DESCRIPTION,'SP. Z O.O.','') AS DESCRIPTION, DATE_FORMAT(a.TRANSACTION_DATE_TIME,'%d-%m-%Y') AS TRANS_DATE FROM bank_book_transaction_master a, bank_book_transaction_details b WHERE a.TRANSACTION_DATE_TIME BETWEEN '2017-12-01' AND '2017-12-26' AND DEBIT_CREDIT_FLAG = 1 AND a.ORG_ID = '53' AND a.BANK_ID = '14' AND a.TRANSACTION_ID = b.TRANS_MASTER_ID

You can do it with a query like this:
UPDATE strtest
SET mystring = CONCAT(
LEFT (mystring, POSITION('SP. Z O.O.' IN mystring)-1),
RIGHT(mystring, LENGTH(mystring)-POSITION('SP. Z O.O.' IN mystring)-9)
)
WHERE mystring LIKE '%SP. Z O.O.%';
Sample:
Test Table
MariaDB [bernd]> SELECT * from strtest;
+----+------------------+
| id | mystring |
+----+------------------+
| 1 | SP. Z O.O. |
| 2 | ABCSP. Z O.O. |
| 3 | SP. Z O.O.XYZ |
| 4 | QWESP. Z O.O.IOP |
| 5 | AAASp. Z o.O.LLL |
+----+------------------+
5 rows in set (0.00 sec)
Remove the String in a SELECT ( The >>><<< are only for test)
MariaDB [bernd]> SELECT CONCAT( '>>>',
-> LEFT (mystring, POSITION('SP. Z O.O.' IN mystring)-1),
-> RIGHT(mystring, LENGTH(mystring)-POSITION('SP. Z O.O.' IN mystring)-9),
-> '<<<') AS resultstring
-> FROM strtest;
+--------------+
| resultstring |
+--------------+
| >>><<< |
| >>>ABC<<< |
| >>>XYZ<<< |
| >>>QWEIOP<<< |
| >>>AAALLL<<< |
+--------------+
5 rows in set (0.00 sec)
To UPDATE the Table
MariaDB [bernd]> UPDATE strtest
-> SET mystring = CONCAT(
-> LEFT (mystring, POSITION('SP. Z O.O.' IN mystring)-1),
-> RIGHT(mystring, LENGTH(mystring)-POSITION('SP. Z O.O.' IN mystring)-9)
-> )
-> WHERE mystring LIKE '%SP. Z O.O.%';
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
MariaDB [bernd]> SELECT * from strtest;
+----+----------+
| id | mystring |
+----+----------+
| 1 | |
| 2 | ABC |
| 3 | XYZ |
| 4 | QWEIOP |
| 5 | AAALLL |
+----+----------+
5 rows in set (0.00 sec)
MariaDB [bernd]>

If you are using MariaDB, you could use REGEXP_REPLACE() like the next line:
REGEXP_REPLACE(col, regexp, replace)
Here you will find examples about the usage.

Related

Get count of zeros in an integer using MySQL

Let's say I have an integer value in MySQL (10090). I need to count all occurrences of the zero digit in that number. So for the previous case it would return 3:
select count_zeros(number) from dual;
-- when number = 10090, it return 3
-- when number = 10000, it return 4
How can I do that the fastest way using a MySQL query?
You can compare the string length with and without the character you want to count.
Solution using LENGTH
-- 0 in 10090: 3
-- 0 in 10000: 4
SELECT
(LENGTH(number) - LENGTH(REPLACE(number, '0', ''))) AS char_count
FROM dual;
A better and safer solution is to use the CHAR_LENGTH function instead of the LENGTH function. With CHAR_LENGTH function you can also count multi-byte characters (like §).
Solution using CHAR_LENGTH
-- § in 100§0: 1
SELECT
(CHAR_LENGTH(number) - CHAR_LENGTH(REPLACE(number, '§', ''))) AS char_count
FROM dual;
You can also extend the above solution to count for a string value using multiple characters.
-- 12 in 10120012: 2
SELECT number,
FLOOR((CHAR_LENGTH(number) - CHAR_LENGTH(REPLACE(number, '12', ''))) / CHAR_LENGTH('12')) AS str_count
FROM dual;
demo on dbfiddle.uk
On MySQL you can create a function to use the above logic on a simpler way:
CREATE FUNCTION GetStringCount(strValue VARCHAR(255), strSearchValue VARCHAR(255))
RETURNS INT DETERMINISTIC NO SQL
RETURN FLOOR((CHAR_LENGTH(strValue) - CHAR_LENGTH(REPLACE(strValue, strSearchValue, ''))) / CHAR_LENGTH(strSearchValue));
You can use this new function GetStringCount like this:
-- example to count non-multi-byte character (here 0).
-- 0 in 10090: 3
-- 0 in 10000: 4
SELECT number, GetStringCount(number, '0') AS strCount
FROM dual;
-- example to count multi-byte character (here §).
-- § in 100§0: 1
SELECT number, GetStringCount(number, '§') AS strCount
FROM dual;
-- example to count a string with multiple characters.
-- 12 in 10120012: 2
SELECT number, GetStringCount(number, '12') AS strCount
FROM dual;
I think the first thing to be done is, casting those integer values to string.
https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast
Then find occurences of a certain char
https://lists.mysql.com/mysql/215049
mysql> create table numbers(x int);
Query OK, 0 rows affected (0,38 sec)
mysql> select * from numbers;
+-----------+
| x |
+-----------+
| 123000 |
| 1300 |
| 135600 |
| 135623400 |
| 13560 |
| 135160 |
| 13514560 |
| 1351120 |
| 13512310 |
+-----------+
9 rows in set (0,00 sec)
Find occurences of zero
mysql> select x, round((length(cast(x as char(11))) - length( replace( cast( x as char(11) ), "0", "" ) ))/length("0")) as str_x from numbers limit 5;
+-----------+-------+
| x | str_x |
+-----------+-------+
| 123000 | 3 |
| 1300 | 2 |
| 135600 | 2 |
| 135623400 | 2 |
| 13560 | 1 |
+-----------+-------+
5 rows in set (0,00 sec)
Find thirteens
mysql> select x, round((length(cast(x as char(11))) - length( replace( cast( x as char(11) ), "13", "" ) ))/length("13")) as str_x from numbers;
+-----------+-------+
| x | str_x |
+-----------+-------+
| 123000 | 0 |
| 1300 | 1 |
| 135600 | 1 |
| 135623400 | 1 |
| 13560 | 1 |
| 135160 | 1 |
| 13514560 | 1 |
| 1351120 | 1 |
| 13512310 | 1 |
| 132134534 | 2 |
+-----------+-------+
10 rows in set (0,00 sec)
mysql>

Changing the fractions in sql

I have fractions as string in my database and it is currently like this:
3/8
I want to change to this:
<sup>3</sup>⁄<sub>8</sub>
I have many fractions like this. How do I change them at one shot in SQL? I know I need to use Regular Expressions but not sure how to use it.
What I have tried so far:
UPDATE question_table
SET `option` = Replace(`option`, ?? ,??)
WHERE `option` LIKE '%/%'
Not sure what to fill up in ??.
SELECT * FROM strings;
+--------+
| string |
+--------+
| 19/32 |
| 3/8 |
| 5/16 |
+--------+
SELECT *
, CONCAT('<sup>'
, SUBSTRING_INDEX(string,'/',1)
, '</sup>⁄<sub>'
, SUBSTRING_INDEX(string,'/',-1)
,'</sub>'
) x
FROM strings;
+--------+-----------------------------------+
| string | x |
+--------+-----------------------------------+
| 19/32 | <sup>19</sup>⁄<sub>32</sub> |
| 3/8 | <sup>3</sup>⁄<sub>8</sub> |
| 5/16 | <sup>5</sup>⁄<sub>16</sub> |
+--------+-----------------------------------+
UPDATE strings
SET string = CONCAT('<sup>'
, SUBSTRING_INDEX(string,'/',1)
, '</sup>⁄<sub>'
, SUBSTRING_INDEX(string,'/',-1)
, '</sub>'
);
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
SELECT * FROM strings;
+-----------------------------------+
| string |
+-----------------------------------+
| <sup>19</sup>⁄<sub>32</sub> |
| <sup>3</sup>⁄<sub>8</sub> |
| <sup>5</sup>⁄<sub>16</sub> |
+-----------------------------------+

DB2 SQL how to make null value become 0?

May I know how to make a null value show in an SQL result as 0?
String SQL = " SELECT A.CNCODE,C.TOTPREM,B.ORDER_AMOUNT,DECIMAL(D.AMOUNT,12,2) AS AMOUNT FROM TB_ORDER A,"+
" TB_ORDER2 B, TB_ORDER3 C LEFT JOIN TB_ORDER4 D ON C.UKEY2=D.UKEY"+
" WHERE C.UKEY2='0012254' AND C.UKEY2=B.UKEY2 AND C.UKEY2=A.UKEY ";
SQL += " WITH UR";
In the current SQL result, amount is shown as "-" indicating NULL; how to make it "0.00"?
===========================================
CNCODE | TOTPREM | ORDER_AMOUNT | AMOUNT
===========================================
I0012254 |136.54 | 5 | -
In mysql you can use coalesce function to convert null as 0 while selecting the data
mysql> select coalesce(null,0);
+------------------+
| coalesce(null,0) |
+------------------+
| 0 |
+------------------+
1 row in set (0.00 sec)
mysql> select coalesce(123,0);
+-----------------+
| coalesce(123,0) |
+-----------------+
| 123 |
+-----------------+
1 row in set (0.00 sec)
Try this Query..
select CNCODE, TOTPREM, ORDERAMOUNT, IFNULL(AMOUNT,0)(select A.CNCODE as CNCODE, C.TOTPREM as TOTPREM,
B.ORDER_AMOUNT as ORDERAMOUNT, DECIMAL(D.AMOUNT,12,2) AS AMOUNT FROM TB_ORDER A,
TB_ORDER2 B, TB_ORDER3 C LEFT JOIN TB_ORDER4 D ON C.UKEY2=D.UKEY
WHERE C.UKEY2='0012254' AND C.UKEY2=B.UKEY2 AND C.UKEY2=A.UKEY ) temp

Mysql with GROUP_CONCAT in subselect

I have problem with subselect in mysql. In table restaurants I have field "sup" where I have IDs separated by comma.
Basic select:
mysql> select name, sup from restaurants LIMIT 5;
+-------------------------------------+---------+
| name | sup |
+-------------------------------------+---------+
| Pizzerija in špagetarija Buf | 2,14,18 |
| EJGA - KAVARNA - RESTAVRACIJA - PUB | 11,17 |
| Restavracija Center | 5,22 |
| Restavracija Viola | 5,13,17 |
| Gostilna Anderlič | 5,17 |
+-------------------------------------+---------+
5 rows in set (0.00 sec)
I want to know the field "SI" from table suply for IDs in sup.restaurants table. So my select for that is:
mysql> SELECT GROUP_CONCAT(suply.SI SEPARATOR ', ') FROM `suply` WHERE id IN (2,14,18);
+---------------------------------------+
| GROUP_CONCAT(suply.SI SEPARATOR ', ') |
+---------------------------------------+
| Italijanska, Špagetarija, Picerija |
+---------------------------------------+
1 row in set (0.00 sec)
So I wrote select with subselct but doesn't work well:
mysql> SELECT restaurants.name,
-> (SELECT GROUP_CONCAT(suply.SI SEPARATOR ', ') FROM `suply` WHERE id IN (restaurants.sup)) AS hrana
-> FROM restaurants
-> LIMIT 5;
+-------------------------------------+--------------------+
| name | hrana |
+-------------------------------------+--------------------+
| Pizzerija in špagetarija Buf | Italijanska |
| EJGA - KAVARNA - RESTAVRACIJA - PUB | Mednarodna kuhinja |
| Restavracija Center | Slovenska domača |
| Restavracija Viola | Slovenska domača |
| Gostilna Anderli? | Slovenska domača |
+-------------------------------------+--------------------+
5 rows in set (0.00 sec)
Why in this select I get just first string?
Use FIND_IN_SET function to search in comma separated list
WHERE FIND_IN_SET(id, restaurants.sup)

mysql, to get rows in tblA that aren't in tblB for an item in tblB

I'm trying to get a query to get the batchuuid from the batchTBL
that aren't in the JobBatchStatusTBL..
I've tried a couple of different queries trying to use something like:
select *
from BatchTBL as ba
left join JobBatchStatusTBL as j
on ba.BatchUUID=j.BatchUUID
join JobTBL as j2
on j.JobUUID=j2.JobUUID
where j.batchuuid IS NULL
and j.JobUUID = 'ecd0fab8-8bf1-83cc-b1d7-495034a55618';
but i'm screwing something up...
any thoughts?
thanks
mysql> select BatchName,BatchUUID from BatchTBL;
+-----------+--------------------------------------+
| BatchName | BatchUUID |
+-----------+--------------------------------------+
| aa | d288ff51-d045-d218-52fd-93e3523db85e |
| aa1 | a288ff51-d045-d218-52fd-93e3523db85e |
| aa3 | d188ff51-d045-d218-52fd-93e3523db85e |
| aaa3 | da88ff51-d045-d218-52fd-93e3523db85e |
| baa3 | db88ff51-d045-d218-52fd-93e3523db85e |
| z1 | 7eedfea4-c498-ed6e-f0dd-1397fe7dbd67 |
| d1 | 34781dba-d99c-82e3-f499-b55ded863f81 |
| nb | 1dd56d9c-daed-7f9f-c13b-246d2ec96513 |
| ds | cca9a771-b5ef-5926-4c26-21151215a800 |
| a1 | 1bb51584-e68a-21d1-a2df-e07707591b43 |
+-----------+--------------------------------------+
10 rows in set (0.00 sec)
mysql> select JobName,JobUUID from JobTBL;
+---------+--------------------------------------+
| JobName | JobUUID |
+---------+--------------------------------------+
| aa | 8afa9cf4-bf63-a4cd-3cd9-cbc6d17f84be |
| aa1 | ecd0fab8-8bf1-83cc-b1d7-495034a55618 |
+---------+--------------------------------------+
2 rows in set (0.00 sec)
mysql> select JobUUID,BatchUUID from JobBatchStatusTBL;
+--------------------------------------+--------------------------------------+
| JobUUID | BatchUUID |
+--------------------------------------+--------------------------------------+
| ecd0fab8-8bf1-83cc-b1d7-495034a55618 | d288ff51-d045-d218-52fd-93e3523db85e |
+--------------------------------------+--------------------------------------+
1 row in set (0.00 sec)
thanks
Your query puts an inner join on JobBatchStatusTbl to JobTbl, so rows that are in one but not the other will never be returned at all. You only need two of the tables for this:
SELECT *
FROM BatchTbl
WHERE JobUUID
NOT
IN (SELECT JobUUID
FROM JobBatchStatusTBL)
I should note that it's impossible to use the JobUUID in the WHERE clause as you're attempting in your initial query, because this is returning only batches for which there is no corresponding job, according to your post - which makes me wonder if your post was misworded, since you had a specific job uuid in your query?
On another note, you should never name tables, columns or anything else in a way that describes their schema type.
Try
select * from BatchTBL where JobUUID not in (select JobUUID from JobBatchStatusTBL)
If I understand what you are trying to do correctly. To "get a query to get the batchuuid from the batchTBL that aren't in the JobBatchStatusTBL"
use the not in SQL syntax. It is easier to write and read, and the optimizer will take care of the rest.
Select BatchName,BatchUUID from
BatchTBL where BatchUUID not in
(Select BatchUUID from JobBatchStatusTBL)