masking the id of an employee in a select query - mysql

I have an ID which I want to mask the last 4 digits of that id.
example: my_id = 123456789
SELECT
concat(left(my_id,length(my_id) -4)) + ' ' + 'xxxx' AS masked_data
FROM
dual ;
Expected output : 12345XXXX
But I am getting as 12345

The strings that you're concatenating should all be arguments to the CONCAT() function. + is for addition, not concatenation.
SELECT
concat(left(my_id, length(my_id) - 4), 'xxxx') AS masked_data
You also don't want a space before xxxx.

Related

match a number using regex for comma separated number

I have a string that contains number with separated by comma like below.
15,22,20,26,33,445,40,44,22,225,115,2
I want to know if a number say 15 is in that string or not.The problem is that 15 and 115 both are a match.Same for other number say 2, for this case 20 , 25, and 225 are match.For both cases only it should return if there is 15 or 2 in the string.I tried using like keyword but it's not working. It also return the rows with 115 or 20, 225, 222 whille matching 15 and 2 respectively. Can anyone suggest a regex pattern?
Update
I have a query like below where I was using like keyword, but I was getting wrong result for above reason.
SELECT DISTINCT A.id,A.title,A.title_hi,A.cId,B.id as cid1,A.report_type ,A.icon_img_url, A.created_at , A.news_date
FROM tfs_report_news A, tfs_commodity_master B
WHERE (',' + RTRIM(A.cId) + ',') LIKE ('%,' + B.id + ',%')
AND A.ccId = B.ccId AND A.`report_type`= "M"
AND A.isDeleted=0 AND A.isActive=1 AND B.isDeleted=0
AND B.status=1
AND A.news_date= (SELECT MAX(T.news_date)
FROM tfs_report_news T WHERE (',' + RTRIM(T.cId) + ',')
LIKE ('%,' + B.id + ',%'))
ORDER BY created_at desc, id desc limit 100;
Here tfs_report_news has the string 15,22,20,26,33,445,40,44,22,225,115,2 as column name cId and individual cId like 15 or 2 is id of tfs_commodity_master
In MySQL, what you asked for is the purpose of string function find_in_set():
Returns a value in the range of 1 to N if the string str is in the string list strlist consisting of N substrings. A string list is a string composed of substrings separated by , characters [...] Returns 0 if str is not in strlist or if strlist is the empty string. Returns NULL if either argument is NULL.
So to check if a value is present in the list, you can just do:
find_in_set('15', '15,22,20,26,33,445,40,44,22,225,115,2') > 0
Side note: here is a recommended reading.
Use FIND_IN_SET:
SELECT
CASE WHEN FIND_IN_SET('15', csv) > 0 THEN 'yes' ELSE 'no' END AS result
FROM yourTable;
Another option would be to use LIKE:
SELECT
CASE WHEN CONCAT(',', csv, ',') LIKE '%,15,%' THEN 'yes' ELSE 'no' END AS result
FROM yourTable;
Finally, you could also use REGEXP here:
SELECT
CASE WHEN csv REGEXP '[[:<:]]15[[:>:]]' THEN 'yes' ELSE 'no' END AS result
FROM yourTable;

MySQL: Extract regexp value from query

I would need to get value from given regexp.
For example:
> :"postalCode";s:4:"3150";
Is there any way I can extract 3150, from this part of column value. Column value stored serialized objects, so postalCode variable can be null type, that way I should check if positive integer follows ;s:POSITIVE_INT:"postalCodeValue
Use SUBSTRING_INDEX:
SELECT
SUBSTRING(SUBSTRING_INDEX(col, '"', -2), 1,
INSTR(SUBSTRING_INDEX(col, '"', -2), '"') - 1) AS num
FROM yourTable;
This query will extract the last quoted number in your string.
Demo
avoiding regexp you could use some string function eg:
SELECT LENGTH(':"postalCode";s:4:"3150"') - LOCATE(':', REVERSE(':"postalCode";s:4:"3150"'))+1
from dual ;
or
SELECT LENGTH(col_name) - LOCATE(':', REVERSE(col_name))+1
from my_table ;
It also work with 2 times SUBSTRING_INDEX
SELECT
SUBSTRING_INDEX (SUBSTRING_INDEX( ':"postalCode";s:4:"3150";', '"',-2) , '"', 1);

SQL: match a string pattern irrespective of it's case, whitespaces in a column

I need to find the frequency of a string in a column, irrespective of its case and any white spaces.
For example, if my string is My Tec Bits and they occur in my table like this, as shown below :
061 MYTECBITS 12123
102 mytecbits 24324
103 MY TEC BITS 23432
247 my tec bits 23243
355 My Tec Bits 23424
454 My Tec BitS 23432
Then, the output should be 6, because, with whites pace removed and irrespective of case, all those strings are identical.
Is there any grep() equivalent in SQL as there is in R?
If your concern is only with the SPACE and the CASE, then you need two functions:
REPLACE
UPPER/LOWER
For example,
SQL> WITH DATA AS(
2 SELECT 'MYTECBITS' STR FROM DUAL UNION ALL
3 SELECT 'mytecbits' STR FROM DUAL UNION ALL
4 SELECT 'MY TEC BITS' STR FROM DUAL UNION ALL
5 SELECT 'my tec bits' STR FROM DUAL UNION ALL
6 SELECT 'MY TEC BITS' STR FROM DUAL UNION ALL
7 SELECT 'MY TEC BITS' STR FROM DUAL
8 )
9 SELECT UPPER(REPLACE(STR, ' ', '')) FROM DATA
10 /
UPPER(REPLA
-----------
MYTECBITS
MYTECBITS
MYTECBITS
MYTECBITS
MYTECBITS
MYTECBITS
6 rows selected.
SQL>
Then, the output should be 6
So, based on that, you need to use it in the filter predicate and COUNT(*) the rows returned:
SQL> WITH DATA AS(
2 SELECT 'MYTECBITS' STR FROM DUAL UNION ALL
3 SELECT 'mytecbits' STR FROM DUAL UNION ALL
4 SELECT 'MY TEC BITS' STR FROM DUAL UNION ALL
5 SELECT 'my tec bits' STR FROM DUAL UNION ALL
6 SELECT 'MY TEC BITS' STR FROM DUAL UNION ALL
7 SELECT 'MY TEC BITS' STR FROM DUAL
8 )
9 SELECT COUNT(*) FROM DATA
10 WHERE UPPER(REPLACE(STR, ' ', '')) = 'MYTECBITS'
11 /
COUNT(*)
----------
6
SQL>
NOTE The WITH clause is only to build the sample table for demonstration purpose. In our actual query, remove the entire WITH part, and use your actual table_name in the FROM clause.
So, you just need to do:
SELECT COUNT(*) FROM YOUR_TABLE
WHERE UPPER(REPLACE(STR, ' ', '')) = 'MYTECBITS'
/
You could use something like
UPPER(REPLACE(userString, ' ', ''))
to check for upper case only and to remove white space.
You could cast your statements to LOWER() before comparing them eg.
LOWER(column_name) = LOWER(variable)
more specific:
LOWER(First_name) = LOWER('JoHn DoE')
would become first name = 'john doe'
For the spacing you should use replace, the format for that is:
REPLACE(yourstring, ' ' , '')
' ' = a space character replace it by an empty string = ''
So you would do
WHERE LOWER(REPLACE(fieldname, ' ', '') = 'mytecbits'
You need to use count to bring back the number affected, Lower will place the data into lower case so that when you make a comparison you can make it lower case.
To remove spaces you then use Replace and replace the space with an empty string for your comparison:
Select COUNT(ColumnA)
from table
where Lower(Replace(ColumnB, ' ', '')) = 'mytecbits'
If you are looking for the number of instances of one specific string, irrespective of case / whitespace, then you need to do the following -
ignore whitespace
ignore case
count the number of instances of the string
So you want a query like the following -
SELECT
COUNT(field)
FROM
table
WHERE
UPPERCASE(REPLACE(field, ' ', '')) = UPPERCASE(REPLACE(userstring, ' ', ''))
This counts the number of rows in your table where field is the same as the userstring, when case is ignored (all set to the same case using UPPERCASE, so it is effecitvely ignored), and spaces are ignored (spaces are removed from the field and the userstring using REPLACE)
Since REGEXP is case insensitive, you can obtain a match by making the spaces optional, example:
SELECT count(field) FROM yourtable WHERE field REGEXP "MY *TEC *BITS";
Note: if needed, you can add a space or a [[:<:]] (word boundary) before "MY" and a space or a [[:>:]] after "BITS" to avoid false positive.

Need help formatting CONCAT() for MySQL query

I have a table where I am attempting to take 3 database table values and reformat them in a single value. Here is the SQL statement that I have at the moment:
SELECT
CASE WHEN cb_cardtype = 'Discover Credit Card'
THEN 'DS'
END +
';' + RIGHT(cardnumbers,4) + ';' + LPAD(MONTH(planexpdate), 2, '0') +
'/' + LPAD(YEAR(planexpdate), 2, '0') AS account_billing_key
FROM my_table
So what I wanted to get as an output here would be:
DS;4242;07/14
The problem is that I am using the + to attempt this, which actually adds the values together. Rather, I understand that I need to use CONCAT() to merge the values. I am unclear about how I can pull the individual values and then concatenate them as desired.
If your query is otherwise correct, all you need to do is to wrap all the strings you want to concatenate - comma separated - inside a call to CONCAT;
SELECT
CONCAT(
CASE WHEN cb_cardtype = 'Discover Credit Card' THEN 'DS' END,
';',
RIGHT(cardnumbers,4),
';',
LPAD(MONTH(planexpdate), 2, '0'),
'/',
LPAD(YEAR(planexpdate), 2, '0')
) AS account_billing_key
FROM my_table

Append text to each row of the sql select query

I have a query like this
SELECT COUNT(ID) 'Records Affected', TYPE FROM MASTER
GROUP BY TYPE
The output for this is
Records Affected TYPE
---------------- ----
4 F1
3 F2
5 F3
Now I would like to change the query so that the output will be as follows
Records Affected
----------------
The number of records affected for F1 is : 4
The number of records affected for F2 is : 3
The number of records affected for F3 is : 5
"The number of records affected for " + TYPE + " is : " + COUNT.
How can I add the default text to each row of the result set instead of appending in the front end. I would like to simplify my task of just showing the records in the DataGrid as Summary.
You can easily concatenate the string using the following. You will use the + to concatenate the string to the type column and the count. Note, the count needs to be converted to a varchar for this to work:
SELECT
'The number of records affected for '+ type +
' is : '+ cast(COUNT(ID) as varchar(50)) as'Records Affected'
FROM yt
GROUP BY TYPE;
See SQL Fiddle with Demo
Just put the text in your query:
SELECT 'The number of records affected for ' + TYPE + ' is : ' + CAST(COUNT(ID) as VARCHAR(20)) AS 'Records Affected' FROM MASTER
GROUP BY TYPE
SELECT "The number of records affected for " + TYPE + " is : " + COUNT(ID) AS [Records Affected]
FROM Master
GROUP BY TYPE
Use this query:
UPDATE bookmark_linx SET link_url=(SELECT CONCAT(link_url, '?raw=true')) WHERE link_url LIKE '%dropbox%'
Try this:
SELECT 'The number of records affected for ' + TYPE + ' is : ' +
STR(X.[Records Affected]) AS [Records Affected]
FROM (SELECT COUNT(ID) 'Records Affected', TYPE FROM MASTER GROUP BY TYPE) X