Change decimal separator in MySQL - mysql

Is it possible to change the decimal comma from "." (dot) to other character (comma) in MySQL output? I don't want to use functions like FORMAT, I just want to use all the queries I normaly use without any modification. I'm looking for some setting (of some variable, locale etc.). I tried to search the manual but without success.

Tip for CSV exports:
SELECT REPLACE(CAST(prijs_incl AS CHAR), '.', ',') will give you input that can be used as numeric fields in european excelsheets.

No, you can't. That's the SQL standard and MySQL complies with it (in that point at least).
The problem is not really with output (as you mention, there are various FORMAT functions in most DBMSs) but with INSERT. If you could use comma , for example as decimal point (that's common in other locales) which is aslo used as values separator, Inserts would become ambiguous. See my answer in the question: insert-non-english-decimal-points-in-mysql

Related

Is it possible to select numeric characters only from a VARCHAR field in MySQL without the use of a custom function?

I'm importing data to a 3rd party CRM and the restrictions on the phone number field are tighter than those of the source database (MySQL). I would like to grab the first 10 numeric characters in the select. I don't have flexibility to sanitize the existing data. I can only work with what is there. All I can find in forums so far seems to be creating a custom function. Is a custom function the only way? The environment is MySQL 5.7.19.
Thanks in advance!
In MySQL 5.7, here's how I'd do it:
SELECT LEFT(mycolumn, 10)+0 FROM ...
The builtin function LEFT() uses only the first N characters.
The +0 makes sure to cast it to a number, just in case the first N characters include some non-numeric characters. Casting to a numeric in MySQL just uses the leftmost number characters, and when it reaches a non-numeric character, ignores the rest.
You can get rid of hyphens first, then use the result of that as I showed above:
SELECT LEFT(REPLACE(mycolumn, '-', ''), 10)+0 FROM ...

Performance in rlike expression or alternate query?

I am doing a series of updates on some tables after I import them from tab-separated values. The data comes with dates in a format I do not like. I bring them in as strings, manipulate them so that they are in the same format as MySQL dates and then convert the column. Or sometimes not, but I want them to be like MySQL dates even if they are strings.
They start out like '1/4/2013 12:00:00 AM' or '11/4/2012 2:37:45 PM'.
I turn these into '2013-01-04' (usually, since times are present even when the original schema clearly specifies dates only) and '2012-11-04 14:37:45'.
I am using rlike. And this does not use indexes? Wow. That sucks.
But already, for each column, I have to use 4 updates to handle the different cases ('1/7', '2/13', '11/2', '12/24'). If I did these using like, it might take 16 different updates for each column....
And, if I am seeing it right, I cannot even get positional parameters out of the rlike expression, yes? You know, the part of the expression wrapped in parentheses that becomes $1 or $2....
So, it seems as though it is going to be quicker to pre-process the tsv file with perl. Really? Wow. Again, this sucks.
Any other suggestions? I cannot have this taking 3 hours every time I need to pull in the data.
Recall the classic 1997 quote from Jamie Zawinski:
Some people, when confronted with a problem, think "I know, I'll use regular expressions."
Now they have two problems.
Have you tried using STR_TO_DATE()? This is exactly for parsing nonstandard date/time strings into canonical datetime values.
If you try parsing with STR_TO_DATE() and the string doesn't match the expected format, the function returns NULL.
So you could try parsing in different formats, and return the first one that gives a non-null result.
UPDATE mytable
SET datecolumn = COALESCE(
STR_TO_DATE(stringcolumn, '%m/%d'),
STR_TO_DATE(stringcolumn, '%d/%m/%Y'),
...etc.
);
I can't tell what your different cases are. It might or might not be possible to cover all cases in one pass.
Another alternative is as you say, preprocess the raw data with Perl before you load it into MySQL. But even then, don't fight with regular expressions, use Date::Parse instead.

Ideas for Find and Replace character

I need to search address fields and change one character to upper case if there is an apartment number. So '521 Main St. #3b' would change to '521 Main St. #3B'.
The way I know to do this would be to write a program that loops through the recordset, looks at the address field for the last character to see if it's an alpha, then if the character before it is a numeric, change the case of the last char and update the record.
Is this something that would be quicker/simpler with regular expressions (haven't ever used)?
If so, is this best done from within a programming environmnet or using a text editor such as Textmate or vi ? The data is in MySQL and Excel, but I can export it to a text file.
Thanks.
I solved this using TextMate which, once I began to understand a little regex, was simple. (details here Regex Syntax for making the last character Uppercase in TextMate)
Still, I wonder if something like sed or awk, (which I started to try out) might be a better tool. And the SQL solution that Olexa provided works. I just don't know how to have it apply to the entire recordset.
If the data is stored in MySQL, then it is better to process it there:
UPDATE addresses
SET address = CONCAT(LEFT(address, CHAR_LENGTH(address) - 1), UPPER(RIGHT(address, 1)))
WHERE address REGEXP BINARY '#[[:digit:]]+[[:lower:]]{1}$'
;
I've added BINARY because otherwise REGEXP is not case-sensitive, but BINARY may need to be omitted to support multi-byte strings. In this case, surplus updates will be made, but the result would be correct anyway.
P. S. An example on SQL Fiddle showing which values are affected, and how they are affected: http://sqlfiddle.com/#!2/b29326/1

How to order text that contains double colons (::)

To order by name I'm using 'order by name'
But the names contain double colons : '::'
How can I order by the text that occurs subsequent to the double colons ?
So :
aaaa::bbbb
aaaa::aaaa
aaaa::1234
aaaa::a1234
Will be ordered :
aaaa::1234
aaaa::aaaa
aaaa::a1234
aaaa::bbbb
Order by the substring ans use locate to find where it starts:
order by substring(name, locate('::', name) + 3, 30)
It'll decrease performance since no index will be used.
You would have to create a new field in MySQL then insert the second part of your text into it. Sort by uses various indexes and algorithms (such as divide and conquer).
As such it would not work on sorting on a specific portion of a specific string, and if you did manage to 'fake' a way of doing it, the performance would be terrible due to lack of indexes.
Sorry, I realise this probably isn't the answer your looking for, but I'm afraid the best way is the slightly longer way, but at least you can then do it at lighting fast speeds if you add an index to it :)
You must split the text into two columns and order by the latter one. You can either split and join the columns in application code or use views and stored procedures to make it look like one column to a database client.
about your sorting , according to ascii values numbers come first before alphabets,
so aaaa:1234 should come first
You can retrieve the values and sort in PHP
Navsort
<?php
$arr = array("aaaa::bbbb","aaaa::aaaa","aaaa::1234","aaaa::a1234");
$sec=$arr;
natsort($sec);
print_r ($sec);
?>
You may try the following approach
Get all records where All data is Alphabet after ::
UNION
Get all records where All data is Numeric after ::

extracting strings from mysql field

total slow moment day, i need to extract different areas based on what language is selected from a field in a mysql database
ex:
<!--:en-->Overview<!--:--><!--:es-->Overview<!--:--><!--:fr-->Présentation<!--:--><!--:ar-->نظرة عامة<!--:-->
so if my language is french for example, i want the part between <!--:fr--> and <!--:-->
any ideas?
Strings processing is not the strongest part of MySQL. But here is one idea:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(column_name, '<!--:fr-->', -1), '<!--:-->', 1) FROM table_name
The easier way would be using a substring. You can find the index for the language on the string first. After that, find the index of the end marker () and extract what's in the middle, which is the value you want.
A more elaborated way would be using regular expressions. The implementation depends on the language you are coding on.