SQL ignore parenthesis in name field for ORDER BY - mysql

I would like rows returned in a MySQL query to be sorted alphabetically by surname for which I have an SQL query like:
SELECT
id,
substring_index(name, ' ', -1) as surname
FROM
my_table
ORDER BY
surname asc
However, some names have parenthesis to denote some special circumstance such as: Laura Angel (retired)
How can I modify my SQL above to ignore the parenthesised text, to sort by surname alphabetically?

Try with nested replaces to remove the parentheses.
SELECT
id,
substring_index(name, ' ', -1) as surname
ORDER BY
REPLACE( REPLACE( surname , '(' , '') , ')' , '') ASC;
Test and modify according to you version of SQL.
Not tested.

You can use this solution:
SELECT id,
substring_index(rtrim(substring_index(name, '(', 1)), ' ', -1) as surname
FROM test.test
ORDER BY
surname asc;

Related

GROUP_CONCAT multiple fields with a different separator

Is it possible to do something like:
GROUP_CONCAT(user, price SEPARATOR ', ') AS items
The result is John3.99, Mike24.99
What I need is something like:
John - 3.99, Mike - 24.99
Basically use another type of separator for price field.
GROUP_CONCAT(CONCAT(user, ' - ', price) SEPARATOR ', ') AS items
Or just
GROUP_CONCAT(user, ' - ', price SEPARATOR ', ') AS items
Try this way
GROUP_CONCAT(
DISTINCT CONCAT(user,',',Price SEPERATOR)
ORDER BY items
SEPARATOR ';'
)

mySQL Replace does not replace second token

I have the Following Query:
SELECT BUSINESS_NAME, 'KEYWORD', REPLACE(BUSINESS_NAME, ' ', '-')
FROM clearindia.business b
LEFT OUTER JOIN `clearindia`.`keywords_master` km ON km.KEYWORD_TEXT = b.BUSINESS_NAME
WHERE km.KEYWORD_TEXT IS NULL
AND b.business_name='Dey Radio Service'
GROUP BY BUSINESS_NAME
It gives me the following results:
# BUSINESS_NAME, KEYWORD, REPLACE(BUSINESS_NAME, ' ', '-')
'Dey Radio service', 'KEYWORD', 'Dey-Radio service'
REPLACE(BUSINESS_NAME, ' ', '-') is not working correctly and does not replace the second space with a '-'. Why is that?
Please Note: BUSINESS_NAME has a collation of utf_unicode_ci.

How to replace non-numiric characters from a string MySQL

I need a better way to replace a non-numeric characters in a string.
I have phone numbers like so
(888) 488-6655
888-555-8888
blah blah blah
So I am able to return a clean string by using a simple replace function but I am looking for a better way may be using expression function to replace any non-numeric value. like space slash, backslash, quote..... any none numeric value
this is my current query
SELECT
a.account_id,
REPLACE(REPLACE(REPLACE(REPLACE(t.phone_number, '-', ''), ' ', ''), ')', ''),'(','') AS contact_number,
IFNULL(t.ext, '') AS extention,
CASE WHEN EXISTS (SELECT number_id FROM contact_numbers WHERE main_number = 1 AND account_id = a.account_id) THEN 0 ELSE 1 END AS main_number,
'2' AS created_by
FROM cvsnumbers t
INNER JOIN accounts a ON a.company_code = t.company_code
WHERE REPLACE(REPLACE(REPLACE(REPLACE(t.phone_number, '-', ''), ' ', ''), ')', ''),'(','') NOT IN(SELECT contact_number FROM contact_numbers WHERE account_id = a.account_id)
AND LENGTH(REPLACE(REPLACE(REPLACE(REPLACE(t.phone_number, '-', ''), ' ', ''), ')', ''),'(','') ) = 10
How can I change my query to use an REGEX to replace non-numeric values.
Thanks
This is a brute force approach.
The idea is to create a numbers table, which will index each digit in the phone number. Keep the digit if it is a number and then group them together. Here is how it would work:
select t.phone_number,
group_concat(SUBSTRING(t.phone_number, n.n, 1) separator '' order by n
) as NumbersOnly
from cvsnumbers t cross join
(select 1 as n union all select 2 union all select 3
) n
where SUBSTRING(t.phone_number, n.n, 1) between '0' and '9'
group by t.phone_number;
This example only looks at the first 3 digits in the number. You would expand the subquery for n to the maximum length of a phone number.
I don't know the mySql regex flavour but I would give this a go:
REPLACE(t.phone_number, '[^\d]+', '')
[^\d]+ means: 'Match everything that is not a digit, once or more times'
You might need to escape the backslash ([^\\d]+).

MySQL split single column

I thought this would be easy... maybe not. I have a table with 'fullname' and I want to split the first name and last name into 2 columns (fname and lname).
The following syntax gives me the data I want:
SELECT
`fullname` ,
SUBSTRING_INDEX( SUBSTRING_INDEX(`fullname` ,' ', 2) ,' ' ,-1) AS fname,
SUBSTRING_INDEX(`fullname` ,' ', 1)AS lname
FROM MyTable
... but how do I then take the 'fname' and 'lname' fields and save them to separate columns in the same table?
[Example data -- If the persons name is John Michael Jones, the 'fullname' field looks like this: JONES JOHN MICHAEL ]
You can just update your table and set the columns to the substrings of the fullname
update MyTable
set fname = SUBSTRING_INDEX(SUBSTRING_INDEX(`fullname` ,' ', 2) ,' ' ,-1),
lname = SUBSTRING_INDEX(`fullname` ,' ', 1)
If you want to perform the update on the same table, you can use the following:
update mytable
set fname = SUBSTRING_INDEX( SUBSTRING_INDEX(`fullname` ,' ', 2) ,' ' ,-1),
lname = SUBSTRING_INDEX(`fullname` ,' ', 1)
See SQL Fiddle with Demo
you want to update into first name ans last name value then you need to used update :
update MyTable
set fname = SUBSTRING_INDEX( SUBSTRING_INDEX(`fullname` ,' ', 2) ,' ' ,-1),
lname = SUBSTRING_INDEX(`fullname` ,' ', 1)
and if you want to set in upper case then user upper function as well as
update MyTable
set fname = upper(SUBSTRING_INDEX( SUBSTRING_INDEX(`fullname` ,' ', 2) ,' ' ,-1)),
lname = upper(SUBSTRING_INDEX(`fullname` ,' ', 1))

can't get subquery inside CONCAT to work

I have this code:
GROUP_CONCAT(
CONCAT(
DATE_FORMAT(je.date_entered, '%m/%d/%Y - %h:%i%p'),
' by ',
'\n',
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(je.description, '<br />', '\n'),
''', '\''),
'"', '"'),
'<', '<'),
'>', '>')
),
'\n\n' ORDER BY je.date_entered DESC SEPARATOR ''
) AS enteries
It works fine. When I add this subquery:
' by ', (SELECT first_name FROM users WHERE id = je.created_by),
resulting in this Group Concat:
GROUP_CONCAT(
CONCAT(
DATE_FORMAT(je.date_entered, '%m/%d/%Y - %h:%i%p'),
' by ',
(SELECT first_name FROM users WHERE id = je.created_by),
'\n',
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(je.description, '<br />', '\n'),
''', '\''),
'"', '"'),
'<', '<'),
'>', '>')
),
'\n\n' ORDER BY je.date_entered DESC SEPARATOR '')
AS enteries
it breaks the whole dang thing, causing no errors, but just returning null.
This may look hairy and tangled but I don't have the option to put everything together in php -- it has to all be done in mysql during the selection process.
p.s. I didn't post the enter query because it is ridiculously long BUT I can if you want me to.
When you use a subquery inside group_concat and concat, they will return:
NULL if the subquery returns 0 rows OR a NULL value
something (presumably good) if the subquery returns 1 row
an error (1242) if the subquery returns more than one row
Presumably your subquery didn't return any rows or returned a NULL value.
Here is my final, working solution:
GROUP_CONCAT(CONCAT(DATE_FORMAT(je.date_entered, '%m/%d/%Y - %h:%i%p'), ' by ', IF((SELECT first_name FROM users WHERE id LIKE je.created_by) IS NULL, '', (SELECT first_name FROM users WHERE id LIKE je.created_by)), ' ', IF((SELECT last_name FROM users WHERE id LIKE je.created_by) IS NULL, '', (SELECT last_name FROM users WHERE id LIKE je.created_by)), '\n', REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(je.description, '<br />', '\n'), ''', '\''), '"', '"'), '<', '<'), '>', '>')), '\n\n' ORDER BY je.date_entered DESC SEPARATOR '') AS enteries