Convert money to text and keep format - sql

I need to show a dollar range in a query but when I concatenate the values I lose the comma in the output.
select
'$'||CAST(ROUND(MIN(db.INITIAL_BALANCE),-1) AS money)
||' to '||
'$'||CAST(ROUND(MAX(db.INITIAL_BALANCE),-1) AS money) AS Balance_Range
the output is
$2060 to $73690
desired output
$2,060 to $73,690
Any suggestions on this?
Intersystems Cache is my database

Why do you think, that you even had commas ?
The documentation says nothing about formatting value.
MONEY and SMALLMONEY are currency numeric data types. The scale for currency data types is always 4.
SELECT CAST('123123' AS money)
this query will return 123123.0000, as expected
As I see, at least there are two ways how to do it.
Define your own datatype, same as %Currency as an example, where you can change scale number, and format. But you should change to this type all properties, in all classes, where you need it.
Or you can define new SQL Function, which will format all numbers as needed.
Something like below:
Class Sample.Utils Extends %RegisteredObject
{
ClassMethod ToMoney(pValue As %Integer = 0) As %String [ SqlProc, SqlName= "TO_MONEY"]
{
quit "$ " _ $fnumber(pValue, ",", 2)
}
}
And Query SELECT Sample.TO_MONEY(1234567), will return $ 1,234,567.00

'$'||TRIM(tochar(MIN(db.Account_Balance),'9,999,999'))|| ' to ' ||'$'||TRIM(tochar(max(db.Account_Balance),'9,999,999'))
gave me what I needed .. Thanks!

Related

How to extract numeric values from a column in SQL

I am trying to extract only the numeric values from a column that contains cells that are exclusively numbers, and cells that are exclusively letter values, so that I can multiply the column with another that contains only numeric values. I have tried
SELECT trim(INTENT_VOLUME)
from A
WHERE ISNUMERIC(INTENTVOLUME)
and also
SELECT trim(INTENT_VOLUME)
from A
WHERE ISNUMERIC(INTENTVOLUME) = 1
and neither works. I get the error Function ISNUMERIC(VARCHAR) does not exist. Can someone advise? Thank you!
It highly depends on DBMS.
in SqlServer you have a limited built-in features to do it, so the next query may not work with all variants of your data:
select CAST(INTENT_VOLUME AS DECIMAL(10, 4))
from A
where INTENT_VOLUME LIKE '%[0-9.-]%'
and INTENT_VOLUME NOT LIKE '%[^0-9.-]%';
In Oracle you can use regex in a normal way:
select to_number(INTENT_VOLUME)
from A
where REGEXP_LIKE(INTENT_VOLUME,'^[-+]?[0-9]+(\.[0-9]+)?$');
MySQL DBMS has also built-in regex
Try this, which tests if that text value can be cast as numeric...
select intent_volume
from a
where (intent_volume ~ '^([0-9]+[.]?[0-9]*|[.][0-9]+)$') = 't'

Automatically change while query "Case When" in Jasper

I have the data whose type is float. I would like to show them as numeric/integer but for just one case, it will show as a float. For the first i thought with Case When in the query, it will be solved but it didn't happen.
i put this code
CASE WHEN SUBSTRING (c.kode_hs,1,2) = '71' THEN CAST(c.brutto AS float) ELSE c.brutto END AS brutto,
CASE WHEN SUBSTRING (c.kode_hs,1,2) = '71' THEN CAST(c.netto AS float) ELSE c.netto END AS netto,
But it didn't turn out to be a float type.
i try to modify the setting of jasper, but it just work for one data type.
There's another alternative i took, i changed the type into number, so that case CASE WHEN SUBSTRING (c.kode_hs,1,2) = '71' worked out. But, unfortunately,when its value was highest (or have much character) was shown as scientific number e.x.: 2E9. That look is definitely ignored in report view. Is it any other solution for me? Thanks anyway
You could select the data from the database as it is, as a float, and do the trick in Jasper.
Set the type of c.kode_hs field in JasperReport as Float, ant the ExpresionClass of the TextBox in which you want to show the value as String. Then set the Text Field Expression as
$F{kode_hs}.toString().substring(0,2).equals("71")?new java.text.DecimalFormat("#0.00").format($F{brutto}):new java.text.DecimalFormat("##").format($F{brutto})
assuming $F{kode_hs} and $F{brutto} are the fields which hold the respective values.

sql strip non-number characters to do avg (average) function on column like "$12.39"

I'm using Rails 3 & postgresql
I have column like -> formatted_price: "$17.99"
How can I use avg on this column?
I tried :
#items = Item.where(:user_id => #category.user_id, :asin => [#category.asins[0..-2].split(',')]).select("asin as asin, title as title, avg(sales_rank) as avg_rank, avg(formatted_price) as avg_price").group(:asin, :title)
getting an error cuz of avg(formatted_price) as avg_price
Quick solution:
AVG(CAST(TRIM(LEADING '$' FROM formatted_price) AS NUMERIC))
Better solution: change the column to a more suitable type, eg money or fixed precision numeric, and format it only when needed for display purposes.
Update: seems from the comments that the column is not formatted uniformly the way it was described in the OP. Although you could follow the suggestion from MatBailie and use substring with a regex to extract the numeric portion to get an average, to me it just does not make sense to take an average of a bunch of monetary values in different currencies.
So, either add a where clause to limit the query to those that are in the currency you want, or go back and rethink what you are trying to do.

SQL Server comma delimiter for money datatype

I import Excel files via SSIS to SQL-Server. I have a temp table to get everything in nvarchar. For four columns I then cast the string to money type and put in my target table.
In my temp table one of those four columns let me call it X has a comma as the delimiter the rest has a dot. Don't ask me why, I have everything in my SSIS set the same.
In my Excel the delimiter is a comma as well.
So now in my target table I have everything in comma values but the X column now moves the comma two places to the right and looks like this:
537013,00 instead of 5370,13 which was the original cell value in the temp and excel column.
I was thinking this is a culture setup problem but then again it should or shouldn't work on all of these columns.
a) Why do I receive dot values in my temp table when my Excel displays comma?
b) how can I fix this? Can I replace the "," in the temp table with a dot?
UPDATE
I think I found the reason but not the solution:
In this X column in excel the first three cells are empty - the other three columns all start with 0. If I fill these three cells of X with 0s then I also get the dot in my temp table and the right value in my target table. But of course I have to use the Excel file as is.
Any ideas on that?
Try the code below. It checks whether the string value being converted to money is of numeric data type. If the string value is of numeric data type, then convert it to money data type, otherwise, return a NULL value. And it also replaces the decimal symbol and the digit grouping symbol of the string value to match the expected decimal symbol and digit grouping symbol of SQL Server.
DECLARE #MoneyString VARCHAR(20)
SET #MoneyString = '$ 1.000,00'
SET #MoneyString = REPLACE(REPLACE(#MoneyString, '.', ''), ',', '.')
SELECT CAST(CASE WHEN ISNUMERIC(#MoneyString) = 1
THEN #MoneyString
ELSE NULL END AS MONEY)
As for the reason why you get comma instead dot I have no clue. My first guess would be cultural settings but you already checked that. What about googling, did you get some results?
First the "separator" in SQL is the decimal point: its only excel that is using the comma. You can change the formatting in excel: you should format the excel column as money and specify a decimal point as the separator. Then in the SSIS import wizard split out the transformation of the column so it imports to a money data type. Its a culture thing, but delimiter tends to be used in the context of signifying the end of one column and the start of the next (as in csv)
HTH
Well thats a longstanding problem with excel. It uses the first 30 or so rows to infer data type. It can lead to endless issues. I think your solution has to be to process everything as a string in the way Yaroslav suggested, or supply an excel template to have data predefined and formatted data type columns, which then have the values inserted. Its a pita.

Comparing Money and Decimal(13,4) columns in SQLServer?

I have 2 different columns in 2 tables, one is with Money datatype in table1 and another one with Decimal(13,4) in table2.I need to sum values in table2 and compare it with value in table1(HAmount).
However i found values like below, please suggest how to compare this.
Table1
HAmount
120.4500
Table2
DAmount
60.2285
60.2200
IF(HAmount=SUM(DAmount))
BEGIN
Success
END
ELSE
Failed
Just convert everything to DECIMAL (13,2):
IF(CAST(HAmount as DECIMAL(13,2) = SUM(CAST(DAmount as DECIMAL(13,2)))
With default rounding settings this should give you the desired output without having to factor in "behind-the-scenes" decimals that aren't displayed.
Please see the convert / cast chart at this Microsoft page. It says that there is an implicit conversion between Decimal and Money.
You might consider using the BETWEEN keyword to help you with fractional pennies.
Both of these datatypes [money and decimal(13,40)] can accurately store values with four decimal places. The full values may or may not be displayed, depending on how SSMS or the user interface of your choice are configured, but they are there. That money value of "120.45" may actually be 120.4485, and the display is rounding it up for you. If not, and if the two values are supposed to add up to the one, then it would seem that you somehow have ended up with corrupt data... and that's a different and more serious problem.
To round numeric functions in T-SQL, you use the ROUND function. Here's a quick example:
declare
#Foo1 money
,#foo2 decimal(13,4)
set #Foo1 = 66.2285
set #Foo2 = 66.2285
print #foo1
print str(#foo1, 7,4) + ' ("true value" of the money value)'
print #foo2
print ''
print round(#foo1,2)
print str(round(#foo1,2), 7,4) + ' ("true value" of the ROUNDED money value)'
print round(#foo2,2)
You want to be very wary when working with imprecise values (i.e. rounding is required), particularly when you're dealing with money!