Trying to convert inconsistently formatted price strings to cents - mysql

I'm migrating data over from one database to another, and am writing the appropriate scripts. I want to start on a clean slate and fix a lot of the inconsistent formatting allowed by the previous app, specifically with prices, the following all being examples of prices currently stored in the previous database:
-100.00
700.00
0.01
3,200.00
3200
1,750.5
0
500/hour
I would like to convert everything into cents, so the above would be:
-10000
70000
1
320000
320000
175050
0
50000
I was hopeful when FORMAT(price, 2) * 100 seemed to work on a lot of them, including (!) 500/hour:
select format('500/hour', 2) * 100;
-> 50000
But for some reason, I'm getting weird results for 3200.00:
select format('3200.00', 2) * 100;
-> 300
While writing this, It appears that it doesn't work for any numeric strings above 1,000, and I'm guessing it has something to do with the presence/lack of a comma. Is there any intelligent way to parse the above examples into cents? If it is simple enough, I'd love to just incorporate it into the select query, but a user defined function is also fine.

You could first remove the comma with this sentence:
replace(data,',','')
This could be because you have a varchar type instead of an int type. If you do
select cast(replace('3,200.00',',','') as signed) * 100
It should work

Related

MySQL-query to retrieve MAX-value doesnt work for decimal numbers

I have a MySQL table that looks like this:
id layer l_to blank
1 1 10 xyz
0 0 5.5 xyz
I want to get the highest number of column-variable "l_to" that shares column-variable "blank".
I have tried the following SQL-query:
SELECT MAX(l_to), COUNT(layer),l_from FROM layers WHERE blank='xyz'
This works fine, if "l_to" of layer 1 is below 10. If it is ten, the query returns "l_to" from layer 0 (5.5).
Any Idea for why this is, and how can I retrieve the MAX?
#EDIT: Changing Datatype of "l_to" from VARCHAR to DECIMAL (5,1) got me the desired result. Thanks for the answers!
The datatype is not a number for field l_to so 5 is greater than 1 for a string. Probably a varchar. Change field l_to to a Decimal [1].
Only consider casting if you do not have control over the table structure as best practice is the data type reflects the data use in the world. This protects the data integrity of the database, provides helpful functions related to the datatype and ensures intuitive outcomes, like Max function. Casting as a work around for this query will only lead to downstream issues; refactor the structure now if you can.
Reference
Decimal data type suggested in comments by #Akina. Originally suggested float, but Decimal appears to reflect the Use Case better than float, given the limited examples shown.
Cast l_to from string to decimal
SELECT MAX(cast(l_to as DECIMAL(10,2)), COUNT(layer) from FROM layers WHERE blank='xyz'
Use a LIMIT query, and also cast the l_to column to decimal:
SELECT *
FROM layers
WHERE blank = 'xyz'
ORDER BY CAST(l_to AS DECIMAL(12.4)) DESC
LIMIT 1;

Access adds extra decimals when grouping in query

Did not found anything to solve this.
I'm doing some easy things on an Access Database 2007 32 bit.
Got this table:
Id_iva Desde Hasta Valor_Iva
2 01/01/2000 31/08/2012 18,00%
4 01/09/2012 31/12/2021 21,00%
5 01/01/2022 31/12/2099 25,00%
Valor_iva is a numeric field, single type. I manually input those numbers, with 2 decimals only (in this case all of them are 0, but it could be something like 18,50% or 20,23% and so on)
If I make a query like this:
SELECT T_IVA.Hasta, T_IVA.Valor_Iva FROM T_IVA;
It works as expected and it returns exactly the values:
But If my query is this:
SELECT T_IVA.Hasta, Sum(T_IVA.Valor_Iva) AS SumaDeValor_Iva FROM T_IVA GROUP BY T_IVA.Hasta;
I get extradecimals in some values.
Can't understand where those decimals come from.
I've googled about CAST and TRUNCATE but I could not apply those (or I don't know how to).
WHAT I WANT: I just want to make a GROUP BY query that does not add those decimals.
Thanks in advance.
If you want exact results, then cast to an exact type before doing any operations. Or, even better, use an exact (non-floating point) type in the first place.
It seems your values fit in the Currency data type. The Decimal data type can be used for larger values with decimals.
SELECT T_IVA.Hasta, Sum(CCur(T_IVA.Valor_Iva)) AS SumaDeValor_Iva FROM T_IVA GROUP BY T_IVA.Hasta;

Trouble displaying ColdFusion Results in proper order when Field length varies 101 vs 1000

I'm using MySQL. I have a table with a field called UnitName. I just want to display all the UnitNames in order. The Unit Names can vary:
101
T-101
G-202
1005
O-1305
When I display them using ORDER BY UnitName, The results are not sorted properly. For instance 1000 will come before 101, T-2000 will come before T-201. If they were all numeric values, I would try to use CAST(UnitName AS INT), but unfortunately I have to deal with the Alpha (and other '-') characters.
I believe the way to approach this is to make sure that the UnitNames have the same length, and then they will sort properly. So basically I am trying to insert a number of zeros into the middle of the string until the lengths are identical and then ORDER BY that.
My query currently is listed below.
<cfquery name="Get"datasource="rent">
SELECT * FROM Units
ORDER BY Left(UnitName,2)+#RepeatString(0, 10-'LEN(UnitName)')#+right(UnitName, 'LEN(UnitName)'-2)
</CFQUERY>
I'm basically saying sort by "the 2 left characters of the string+(a number of 0s determined by the number 10 minus the length of the string)+the characters on the right side of the string (except the first 2).
When I just do a CFOUTPUT of this the UnitName comes out perfectly. I do have to had some # to make it work: #Left(UnitName,2)##RepeatString(0, 10-'#LEN(UnitName)#')##right(UnitName, len(UnitName)-2)#
But the query fails to execute as written below. I've narrowed it down to the middle section where I'm trying to determine the number of Zeros to insert. Specifically if I use:
#RepeatString(0, 10-5)#, the query will execute. But the minute I put 'LEN(UnitName)' instead of 5, the query fails. Any idea what I'm doing wrong?
Any insight is appreciated--I've been banging my head against a wall.

Alphanumeric Sorting SSRS

I have a report that creates a parts list from my MFG software. The part number list currently looks like this:
DA100-12
DA100-121
DA100-122
DA100-13
DA100-131
I want them to sort taking into account the numeric part at the end like this:
DA100-12
DA100-13
DA100-121
DA100-122
DA100-131
Does anyone have suggestions on how to accomplish this within a report?
You could split at the - and then sort by the last part numerically. One solution would be to do this in the underlying database query already, maybe like this:
SELECT PartNo, SUBSTR(PartNo, 1, CHARINDEX('-', PartNo)) AS PN, CONVERT(INT, SUBSTR(PartNo, CHARINDEX('-', PartNo) + 1, LEN(PartNo))) AS NumPart
You may need to tweek the SUBSTR indices a bit, I can not actually try this right now. Then have SSRS sort by PN and NumPart. The result of the query should look something like this:
PartNo PN NumPart
---------------------------
DA100-12 DA100 12
DA100-121 DA100 121
DA100-122 DA100 122
DA100-13 DA100 13
DA100-131 DA100 131
I'm pretty sure that you can also do the splitting in SSRS itself, too, in the sort expression.
You can also leverage the T-SQL function PARSENAME for this, if there are no '.' characters in your data and if there is always exactly one '-' separating the parts. (Ultimately, you may be better off redesigning things so the two parts of the part name are in separate columns.)
select * from Parts
order by
PARSENAME(REPLACE(PartName,'-','.'),2),
CAST(PARSENAME(REPLACE(PartName,'-','.'),1) AS INT)
Click here for a SQL Fiddle repro.

MySQL is cutting '00' in decimals

I have a table with a decimal column with a lenght = 9 and decimals = 2.
If I put a value of 21.59 (for example) it works ok.
If I put 52.00 it writes only 52. I need to keep 52.00 instead.
Master question: Can the database store the value this way? Instead of
using format/cast in select to retrieve the value...
As noted bellow, this make sense:
"You shouldn't worry about display formatting issues at the database
level but at the ... display level"
Use the FORMAT function:
select format(mycolumn, 2) from mytable;
This also has the effect of adding thousand's separator into the number, so you would get output like 123,456.70. There are workarounds if this doesn't work for you.
Given that MySQL doesn't have the world's best facilities for formatting numbers, display issues like this are usually handled in client code.