I'm just getting used to MySQL, I've come from a SQL Server background...
This SQL query builds an address how it should in SQL Server, how can I adapt it to use within MySQL. When I run it in SQL Server it displays all the data within each field, when run in MySQL it just shows me the first field.
Why would this be, what should I do different in MySQL?
SELECT COALESCE(House, '') + ' ' + COALESCE(StreetName, '') + ' ' + COALESCE(TownCity, '') + ' ' + COALESCE(Postcode, '') AS Display
FROM MyTable
WHERE Postcode LIKE '%A1 2AB%'
Use the concat() function:
SELECT concat(COALESCE(House, ''), ' ', COALESCE(StreetName, ''), ' ',
COALESCE(TownCity, ''), ' ', COALESCE(Postcode, '')
) AS Display
FROM MyTable
WHERE Postcode LIKE '%A1 2AB%';
You can also do this with concat_ws(). This eliminates the need for all the spaces:
SELECT concat_ws(COALESCE(House, ''), COALESCE(StreetName, ''),
COALESCE(TownCity, ''), COALESCE(Postcode, '')
) AS Display
FROM MyTable
WHERE Postcode LIKE '%A1 2AB%';
What happens in MySQL is that the + does just what you expect: it adds numbers. A string that contains a number is converted to a number automatically, with silent errors for strings that have no numbers. In practice, this means that a string that starts with a non-digit (and non-decimal point) is converted to a 0.
So, house, which presumably usually numeric, is converted to a number just fine. All the other strings are converted to numbers but become zero and the house number is not changed. You would have gotten much different results if your post codes were American-style zip codes (which are typically numeric).
EDIT:
As #fthiella points out, the coalesce() is not necessary for concat_ws(). The two statements would do different things, because NULLs in the original query result in repeated separators. NULLs in the concat_ws() version would have only a single separator (which might be desirable).
However, I would tend to keep the coalesce() anyway. The behavior of concat() and concat_ws() varies in this regard. concat() returns NULL if any of its arguments is NULL. concat_ws() skips NULL arguments after the initial separator. Who can remember that distinction? It sounds like a recipe for confusion in production code. So, I would also use coalesce() even though it is optional.
Related
I am working on a legacy system a client has. Phone numbers are stored in a multitude of ways. Ex:
514-879-9989
514.989.2289
5147899287
The client wants to be able to search the database by phone number.
How could this be achieved without normalizing the data stored in the database? Is this possible?
I am wondering if it is possible to have a query that looks like:
SELECT FROM table WHERE phonenumber LIKE %input%
but that takes into account only the numerical characters in the db?
$sql = "SELECT * FROM tab
WHERE replace(replace(phone, '.', ''), '-', '') like '%". $input ."%'"
Yes you can add more replace according to values in your table, as mentioned by #spencer7593 eg:
$sql = "SELECT * FROM tab
WHERE replace(replace(replace(replace(replace(replace(phone, '.', ''), '-', ''), '+', ''), '(', ''), ')', ''), ' ', '') like '%". $input ."%'"
but I would prefer to cleanup the data before the query.
The approach I would take with this (i.e. not having a "normalized" value with only digits available, and a restriction of not adding an additional column with the normalized value...)
I would take the user input for the search, and add wild cards in strategic locations. For example, if the user provides search input of 3155551212), then I'd run a query that has a predicate equivalent to this:
phonenumber LIKE '%315%555%1212%'
But if I'm not guaranteed that the provided search digits will be a full three digit area code, a three digit exchange (central office) code, and a four digit line number, for a broader search, I'd add wild cards between all of the provided digits, e.g.
phonenumber LIKE '%3%1%5%5%5%5%1%2%1%2%'
This latter approach is less than ideal, because it could potentially provide more matches than aren't intended. Especially if the user is providing fewer than ten digits. For example, consider a phonenumber value:
'+1 (315) 555-7172 ext. 123'
As a demonstration:
SELECT '+1 (315) 555-7172 ext. 123' LIKE '%3%1%5%5%5%5%1%2%1%2%'
, '+1 (315) 555-7172 ext. 123' LIKE '%315%555%1212%'
There's no builtin string function in MySQL that will extract the digit characters from a string.
If you want a function that does that, e.g.
SELECT only_digits_from('+1 (315) 555-7172 ext. 123')
to return
13155557172123
You'd have to create a stored function that does that. I wouldn't attempt doing it inline in the SQL statement, that would require an atrociously long and ugly expression.
This is piece of code i frequently use to clean up the database columns. I have modified to to be fit for your purpose.
Update Table SET Column =
replace
(replace
(replace(column,
'-','',
'.',''),
' ','')
)
WHERE Column is Not Null
I'm working on MySQL and having column phone-number. And trying to use regex for this and not succeed.
How can I remove all special character from this column ?
phone-number
'8-903-400-65-38'
'+79265682388'
'8.10492E+15'
'8-913-469-38-35'
'+79882856253'
'+79110987703'
'+7 (495) 989-21-16'
'8142 77-55-51'
'+79378299427'
Please can anyone help me on this issue? I don't want to lose these list of contact numbers.
Thanks in advance
The canned answer here is just to chain together a series of calls to MySQL's REPLACE function:
SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(phone-number, '-', ''), '+', ''), '.', ''), '(', ''), ')', ''), ' ', '')
This would remove the following characters from the phone-number column:
- + . ( ) and space
The nicer solution would be to use a regular expression to do the replacement, but alas MySQL does not any such built in support for regex replace.
If you don't want a fugly REPLACE chain, then you could write some dynamic MySQL code which iterates over a set of characters which you define, and does a number of updates to the table. Here is what one such update would look like:
UPDATE yourTable
SET phone-number = REPLACE(phone-number, '+', '')
You could perform one update for each character and handle it this way.
So I have a column of strings in a format like this: '123.123.123.123.123'.
I need to cut the string to the first two numbers like so: '123.123' that way I can GROUP BY the cut string to get the results needed.
I can do this easily by using SUBSTRING_INDEX(Version, '.', 2) however the problem arises when the second number part has multiple 0's therefore giving me duplicate entries in the query.
e.g. (10.00, 10.0) and 10.404, 10.4040 etc.
Is there a way to trim all unwanted zeros off the end of the string?
Note: I can only use straight MySQL or functions in this case.
EDIT:
I can get the desired result by replacing the first instance of '.0', trim the extra zeros and then replace the '.0' back
REPLACE(TRIM(TRAILING '0' FROM REPLACE(SUBSTRING_INDEX(Version, '.', 2), '.0', '^a')), '^a', '.0')
This probably is not the best option performance wise - therefore I will wait for others before accepting my own.
If you are only working with the first two components, then convert the values to a number, say:
cast(substring_index(version, '.', 2) + 0 as decimal(10, 4))
This will give everything with equal numeric values the same representation.
EDIT:
If you want to remove the trailing zeros from the end of the string, you can use this trick:
replace(rtrim(replace(substring_index(version, '.', 2), '0', ' ')), ' ', '0')
This replaces the zeros with spaces, then uses rtrim() and converts them back to zeroes.
I'm trying to remove parenthesis from the area code of a number. I'm able to do so but when I try to concatenate the two Replace functions, the numbers repeat with only one parenthesis removed.
This is what I tried so far:
SELECT HomePhone, REPLACE(HomePhone, '(', '') +
REPLACE(HomePhone, ')', '') AS Expr1
FROM dbo.Employees
http://i.imgur.com/4iJoFzE.png
Nest don't add
Replace(Replace(HomePhone,')',''),'(','')
Look at how the function replace works. It expects string With Text To Evaluate, string to replace, string to replace with)
By adding them you should be getting the number listed twice, but if the data type isn't long enough it may be truncating values. by nesting you're telling the system to replace the ) and then use that string w/o the ) to have the ( replaced with ''.
You cannot concatenate in this way, you must use the concat function in SQL. Or use thus:
SELECT HomePhone, REPLACE(REPLACE(HomePhone, ')', ''), '(', '') AS Expr1 FROM dbo.Employees
In not a database guy but: I have mixed up data in a mySql database that I inherited.
Some Phone numbers are formatted (512) 555-1212 (call it dirty)
Others 5125551212 (Call it clean)
I need a sqlstamet that says
UPDATE table_name
SET Phone="clean'(Some sort of cleaning code - regex?)
WHERE Phone='Dirty'
Unfortunately there's no regex replace/update in MySQL. If it's just parentheses and dashes and spaces then some nested REPLACE calls will do the trick:
UPDATE table_name
SET Phone = REPLACE(REPLACE(REPLACE(REPLACE(Phone, '-', ''), ')', ''), '(', ''), ' ', '')
To my knowledge you can't run a regexp to replace data during the update process. Only during the SELECT statement.
Your best bet is to use a scripting language that you're familiar with and read the table and change it that way. Basically by retrieving all the entries. Then using a string replace to match a simple regexp such as [^\d]* and remove those characters. Then update the table with the new value.
Also, see this answer:
How to do a regular expression replace in MySQL?