MySQL Decimal format - mysql

I have 2 TEXT columns in my table (AmountPaid and AmountRemaining). The format is € 10.000,00
I am trying to create a query that pluses these 2 values, and convert it back to the format as show above (€ 10.000,00). Of course this should also work with for example € 100.000.000,00, € 690,00 or € 10,00 etc...
For now I have this query witch plusses the values:
SELECT AmountRemaining, CAST(REPLACE(REPLACE(REPLACE(CAST(AmountRemaining AS CHAR), '€ ', '') , '.', ''), ',00', '') AS DECIMAL) +
CAST(REPLACE(REPLACE(REPLACE(CAST(AmountPaid AS CHAR), '€ ', '') , '.', ''), ',00', '') AS DECIMAL) FROM Clients
The output of this is like this "10000", "13000" etc...
How can I convert this back to the original format?
Thanks.

I have 2 TEXT columns in my table.
Wrong. Text columns contain text. Use numeric columns for numbers. That is, cleanse the data on the way in, not on the way out.
Once you have done that, the rest is better done thus:
Use LOCALE to establish the desired decimal point and thousands separator. That is used in the FORMAT() function to do the rest of the numeric part. T tack on the currency symbol, use CONCAT().
SELECT
CONCAT('€', FORMAT(1234567, 2, 'de_DE'));
+--------------------------------------------+
| CONCAT('€', FORMAT(1234567, 2, 'de_DE')) |
+--------------------------------------------+
| €1.234.567,00 |
+--------------------------------------------+

Related

MYSQL : Find the last occurrence of a character in a string

Length will be dynamic and i want to find the data before last occurrence of a character in a string in MYSQL
Like strrchr in php
To get last occurrence of _ (underscore) I need to pass length. and here it's 3
mysql> SELECT SUBSTRING_INDEX ('this_is_something_here', '_', 3);
+----------------------------------------------------+
| SUBSTRING_INDEX ('this_is_something_here', '_', 3) |
+----------------------------------------------------+
| this_is_something |
+----------------------------------------------------+
And here, to get last occurrence of _ (underscore) i need to pass length. and here it's 6
mysql> SELECT SUBSTRING_INDEX ('and_this_may_go_like_this_too', '_', 6);
+-----------------------------------------------------------+
| SUBSTRING_INDEX ('and_this_may_go_like_this_too', '_', 6) |
+-----------------------------------------------------------+
| and_this_may_go_like_this |
+-----------------------------------------------------------+
i want data string before last occurrence of _ (underscore) just shown in above example but without passing length.
Note : from above example i want before data of "_here" and "_too"
last occurrence of _ (underscore)
Is there any built-in functionality to achieve this in MySQL?
Thanks in advance amigos.
I didn't quite get your examples, but I think what you want is to pass -1 as the length and prepend the substring prior.
Compare
strrchr('and_this_may_go_like_this_too', '_'); // Returns _too
SELECT SUBSTRING_INDEX('and_this_may_go_like_this_too', '_', -1);
-- Returns too, just need to concatenate `_` so...
SELECT CONCAT('_', SUBSTRING_INDEX('and_this_may_go_like_this_too', '_', -1));
-- Returns _too
If you're looking for the part of the string before and up to the needle, and not from the needle to the end of the string, you can use:
SET #FULL_STRING = 'this_is_something_here';
SELECT LEFT(#FULL_STRING, LENGTH(#FULL_STRING) - LOCATE('_', REVERSE(#FULL_STRING)));
-- Returns this_is_something
Note that the second statement is not what strrchr does.
select reverse(substr(reverse('this_is_something_here'), 1+locate('_', reverse('this_is_something_here'))));
Use reverse, locate, right then replace without using length
Set #str = 'there_is_something';
Select replace(#str,right(#str,locate('_',reverse(#str))),'');
You can write query like this
SELECT SUBSTRING_INDEX('and_this_may_go_like_this_too','_',(LENGTH('and_this_may_go_like_this_too')-LENGTH(REPLACE('and_this_may_go_like_this_too' ,'_',''))) - 1);

Custom SQL query, for sorting values with "-" as separators

I am trying to create an ORDER BY to sort my values properly.
The values contain a string and anywhere from zero to three sets of numbers separated by a -.
Example:
dog-2-13
dog-13-54-3
dog-25
cat-63-12
cat
I want them to be sorted firstly by the string in front and then by each of the "number sections" so that: dog-2-14 > dog-2-13 but dog-1-14 < dog-2-13.
Expected result (with more examples to make it clearer):
cat
cat-63-12
dog-2-13
dog-2-14
dog-3
dog-13-53-3
dog-13-54-3
dog-13-54-4
dog-25
I'm a SQL novice and completely lost. Thank you!
Please try...
SELECT fieldName
FROM
(
SELECT fieldName AS fieldName,
SUBSTRING_INDEX( fieldName,
'-',
1 ) AS stringComponent,
CONVERT( SUBSTRING_INDEX( SUBSTRING( fieldName,
CHAR_LENGTH( SUBSTRING_INDEX( fieldName, '-', 1 ) ) + 2 ),
'-',
1 ),
UNSIGNED ) AS firstNumber,
CONVERT( SUBSTRING_INDEX( SUBSTRING( fieldName,
CHAR_LENGTH( SUBSTRING_INDEX( fieldName, '-', 2 ) ) + 2 ),
'-',
1 ),
UNSIGNED ) AS secondNumber,
CONVERT( SUBSTRING( fieldName,
CHAR_LENGTH( SUBSTRING_INDEX( fieldName, '-', 3 ) ) + 2 ),
UNSIGNED ) AS thirdNumber
FROM table1
ORDER BY stringComponent,
firstNumber,
secondNumber,
thirdNumber
) tempTable;
The inner SELECT grabs the field name (which I am assuming is fieldName) and the three components and places each in a separate field and assigning an alias to that field. Each subfield must be included at this point for sorting purposes. The list is then sorted based upon those values.
Once this sorting is performed the outer SELECT chooses the original field from the list in a now sorted order.
The four outer instances of SUBSTRING_INDEX() are used to grab the desired fields from their first argument. As SUBSTRING_INDEX() grabs all of the string from the beginning to just before the first occurence of the delimiting character this makes finding the first field easy (Note : I am assuming that the first field shall contain no hyphens).
The first argument for the remaining occurences of SUBSTRING_INDEX() is formed by using SUBSTRING() to grab everything from just after the parsed part of fieldName and the following delimiting character. It is told where this is by using CHAR_LENGTH() to count the number of characters before the most recent delimiting character then adding 1 for the most recent delimiting character and another 1 to point SUBSTRING() to the character after the most recent delimiting character.
SUBSTRING_INDEX() will return NULL where it encounters an absent numerical field. Please note that NULL has a different sort value from zero.
The numerical fields are converted into unsigned Integers using CONVERT(). Unsigned integers were chosen as the supplied data does not contain any real numbers. If there are real values then you will need to replace UNSIGNED with DECIMAL. I have also assumed that all of the numbers will be positive.
Further reading...
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_substring-index
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_substring
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_char-length
https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert
If you have any questions or comments, then please feel free to post a Comment accordingly.
You can use a Query like this:
SELECT *
FROM yourTable
ORDER BY SUBSTRING_INDEX( SUBSTRING_INDEX(cat,'-',2), '-', -1);
sample
mysql> SELECT SUBSTRING_INDEX('dog-13-54-4','-',2);
+--------------------------------------+
| SUBSTRING_INDEX('dog-13-54-4','-',2) |
+--------------------------------------+
| dog-13 |
+--------------------------------------+
1 row in set (0,00 sec)
mysql>
mysql> SELECT SUBSTRING_INDEX( SUBSTRING_INDEX( 'dog-13-54-4','-',2), '-', -1);
+------------------------------------------------------------------+
| SUBSTRING_INDEX( SUBSTRING_INDEX( 'dog-13-54-4','-',2), '-', -1) |
+------------------------------------------------------------------+
| 13 |
+------------------------------------------------------------------+
1 row in set (0,00 sec)
mysql>

MySQL - Return from a string the leftmost characters from 2 different characters

I have a database with some codes seperated by / or -, I want to show the left side only, this is an example of the data:
45/84
12/753
68-53
15742-845
2/556
So, i want to get this:
45
12
68
15742
2
I tried using LEFT(), but this search for 1 character only, and returns a warning if the character is not found, this is what LEFT(field,'/') returns.
45
12
(WARNING)
(WARNING)
2
So, what about a REGEXP?
an IF?
any way to ignore from the first non numeric character?
I dont' have more ideas...
Thank you!
Try this:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(col, '-', 1), '/', 1)
FROM mytable
Demo here
You can do it with this statement. Replace the string '15742/845' with your fieldname
SELECT SUBSTRING_INDEX( REPLACE('15742/845','/','-'), '-', 1)

Convert text to float, when text comes in different formats

I want to store a text as a float. My problem is, that this text comes in different formats , and I cannot influence that. My TEXT column contains strings like
357000
218000.56
500.000.00
I don't have a problem converting the first two strings. I DO have a problem converting the last one, because the decimal mark is the same character as the thousands separator.
How should I deal with this problem? Is there an explicit conversion string-to-float using a format I can define?
EDIT: I forgot to say, that in the above cases, the last . (if there is any) is always the decimal separator if it is followed by a two digits number. So, '153.650' should convert to 153650 for example.
"EDIT: I forgot to say, that in the above cases, the last . (if there is any) is always the >decimal separator if it is followed by a two digits number. So, '153.650' should convert to >153650 for example."
There's your answer.
Check if the character at index (yourString.Length - 3) is one of your delimiters. If it is, then you have a decimal value; if not, you don't. Proceed to strip out all extraneous symbols and then re-insert your choice of decimal separator at the correct index.
Clean? No. But the situation stinks, TBH.
Correct the data before giving them to SQL - a programming language is simpler, for instance using regular expression replace.
s = s.replaceAll("\\D(\\d\\d\\d)", "$1").replaceFirst("\\D". ".");
(Which does not consider signs!)
It first removes non-digits followed by three digits, and then make a period out of the first remaining non-digit. Can be done smarter.
The above is Java, but regex exists in all sensible programming languages.
you can try this
CONVERT(
REPLACE(REPLACE(value, '.', ''), ',', '.'),
DECIMAL(10,2))
this will replace . and, from your string and will convert it into decimal (10,2).
According To Your
SELECT
IF(
LENGTH(
SUBSTRING_INDEX('351.000', '.', - 1)
) >= "3",
CONVERT(
REPLACE("351.000", ".", ''),
DECIMAL (10, 2)
),
CONVERT(
CONCAT(
REPLACE(
LEFT(
'351.000',
LENGTH("351.000") - LOCATE('.', REVERSE("351.000"))
),
'.',
''
),
CONCAT(
".",
SUBSTRING_INDEX('351.000', '.', - 1)
)
),
DECIMAL (10, 2)
)
)
I have tried for
1234.56 gives 1234.56
1234.000.00 gives 1234000.00
and 1234.000 gives 1234000
but it is not a good way to do so much in mysql query. you should handle it in programming part
SQL Fiddle
MySQL 5.5.32 Schema Setup:
CREATE TABLE Table1
(`TEXT` varchar(10))
;
INSERT INTO Table1
(`TEXT`)
VALUES
('357000'),
('218000.56'),
('500.000.00')
;
Query 1:
SELECT CAST(concat(
REPLACE(CASE WHEN substr(TEXT,-3,1) = "." THEN substr(TEXT,1,length(TEXT)-3)
ELSE TEXT END,'.',''),
CASE WHEN substr(TEXT,-3,1) = "." THEN right(TEXT,3)
ELSE '' END) AS decimal(12,2)
) AS Amount
FROM Table1
Results:
| AMOUNT |
|-----------|
| 357000 |
| 218000.56 |
| 500000 |

MySQL Logical Operators in a field with text and integers

I have a table that looks like:
ATTRIBUTE1 | ATTRIBUTE2
weight: 190| height: 175
ctr: 400 | dmd: 19
Is it possible to do comparative operations on these fields?
Like, if I wanted to find everyone with a weight less than 200, what would the syntax look like for that? I figure the query would look like the following, if there were no text in the field:
SELECT * FROM mytable WHERE attribute1 < '200'
But since the field has the defining text "weight:", I'm not quite sure how to do this.
Rather
CAST(SUBSTRING(attribute1, INSTR(attribute, ': ') AS SIGNED)
because the value contains the string in the beginning.
Basically you do like this:
Find the index of ': ' and use it as a substring for the value (to skip everything until the actual number). Then you cast it to an Int
(maybe you need to add a +1 to INSTR. I'm not sure since i don't have a mysql client right here
where cast(substring(ATTRIBUTE1, instr(ATTRIBUTE1, ': ')+1 ) as unsigned) <200
alternative:
where cast(replace(Field_2, 'weight: ', '') as unsigned) > 180