Formatting Number Field to Currency Using TO_CHAR returning hash characters - sql

I am running a simple sum and conversion to currency on a NUMBER field in an Oracle database.
My query is:
select
TO_CHAR(eve.data_entry_date, 'yyyy-mm'), wtc.description as WORK_TYPE,
TO_CHAR(sum(sev.amount),'$999,999.99') AS "Total Invoice Amount"
from
EVENT eve,
SOW_EVENT sev,
WORK_TYPE_CODE wtc,
SOW_WORK_TYPE_XREF swt,
WORK_TYPE_ITEM_CODE wti
where
eve.event_number_id = sev.event_number_id
and sev.WORK_TYPE_CODE = WORK_TYPE_CODE
and sev.event_number_id = swt.event_number_id
group by
TO_CHAR(eve.data_entry_date, 'yyyy-mm'), wtc.description
The query runs successfully, however the amounts showing up in the "Total Invoice Amount" column are returning hashes like:
Year-Month WORK_TYPE Total Invoice AMount
2019-01 Physical Work ############
2019-01 Technical Work ############
I had thought I just needed to resize the column, but that didn't work. When I just run:
sum(sev.amount)
it populates the amounts, just not formatted as currency as the 'amount' column is a number column. Any idea why I am getting the hashes when I format to currency?

From the documentation:
All number format models cause the number to be rounded to the specified number of significant digits. If a value has more significant digits to the left of the decimal place than are specified in the format, then pound signs (#) replace the value. This event typically occurs when you are using TO_CHAR with a restrictive number format string, causing a rounding operation.
Your format mask needs enough digit placeholders for the highest value you expect to see. At the moment the values seem to be above a million.

Related

How can I sum a column of $90 then $20 without removing the dollar sign in access query criteria

It gives me error that data type mismatch in criteria expression , but can sum it without removing the dollar sign
The $ sign is for display only. The values are truly numerics.
So, sum, add, or filter as for other numbers, and then apply the format, Currency, where you wish to display the totals.

How to calculate the avg time a tool stays on hold? oracle sql developer

Im trying to calculate the average time a tool stays on loan. The time a tool stays on loan is the number of days between loan_status_change_date and tool_out_date (table columns). the date type of these 2 columns is ex: 01-SEP-17
whats the best way to approach this?
We can do arithmetic with Oracle dates. It's not clear from the column names which one is the start of the loan and which the end; in the following example I've assumed loan_status_change is when the tool is returned.
select tool
, avg(loan_status_change - tool_out_date) as avg_loan_days
from your_table
group by tool
/
The AVG() function is an aggregate function, so it handles the /ns for us. The substraction is to calculate the length of a particular loan, which is the value you want to average. The result of that substraction already is a number of days, so no further transformation is necessary. If your columns have a time element then the result might not be an integer.

SQL Server : aggregate function doesn't work?

I have imported a price list from a csv to my SQL Server database. That has worked fine. But now some weird stuff. Table is named PRICE which includes a column (and some more) Endprice and a total of 761 rows. All datatypes are varchar(50).
SELECT MAX(Endprice)
FROM PRICE
When I want this simple SQL statement to show the highest price in the column, I get a wrong result. I don't know why.
I get 98,39 as a result, but that's definitively wrong, it must be 100,73.
Here you can see a part of the data:
And now the wrong MAX() result:
BUT when I'm using the MIN function I get the highest one!? The min is somewhere at ~50 (not shown in the screenshot part).
`
The resultset of SELECT Endprice FROM PRICE is correct. I am at my wit's end.
This is because your column is a varchar, so it is determining the min or max based on characters. The column should be a decimal or money type, so it sorts by the value of your number (instead of an alphabetic sort like you are getting now).
Alphabetic sort: 9 is more than 1, thus 98.39 is the max.
The reason is because price is a varchar().
Here are two solutions:
order by len(price), price
This works assuming that all the price values have the same structure.
Or:
order by cast(price as float)
If you could have non-numeric values (always a danger when storing numbers in the wrong data type):
order by (case when isnumeric(price) = 1 then cast(price as float) end)
Or better yet:
alter table alter column price money
Then you don't have to worry about having the wrong type for the column.
Your problem is Endprice columns is varchar(50), therefore it is comparing strings not numbers, which means that a 9>1 no matter what cames next of the first digit. You have to convert it to a number before the max!
Also you really should consider in doing what #a_horse_with_no_name suggested change your column into a number like column type.
This is a example on how you solve your actual problem
select max(cast(endprice as money)) from sample
See it here: http://sqlfiddle.com/#!3/767f6/1
Note that I used . as a decimal separator it will depend on your database language setup.

Arithmetic overflow error converting numeric datatype to numeric

I'm having following columns in a table
SIZE NUMERIC(14,5)
PRICE NUMERIC(14,5)
when I perform this select query,
SELECT SIZE,
PRICE,
SIZE*PRICE AS TOTAL
FROM TNAME
I'm getting results:
1.00000 90.00000 90.0000000000
1.00000 90.00000 90.0000000000
1.00000 90.00000 90.0000000000
1.00000 100.00000 100.0000000000
1.00000 30.00000 30.0000000000
I'm wondering why the third column is returning with 10 digits after decimal point?
Also I'm getting
Arithmetic overflow error converting numeric datatype to numeric
while inserting result into another table which has the same columns with same datatype
INSERT INTO TNAME2(SIZE, PRICE, TOTAL)
SELECT
SIZE, PRICE, SIZE * PRICE AS TOTAL
FROM
TNAME
Try This.
SELECT SIZE,
PRICE,
CAST(SIZE*PRICE AS numeric(14,5))AS TOTAL
FROM TNAME
INSERT INTO TNAME2
SELECT SIZE ,
Price ,
CAST(SIZE * PRICE AS NUMERIC(15, 5))
FROM TNAME
OR
INSERT INTO TNAME2 (SIZE,Price,TOTAL)
SELECT SIZE ,
Price ,
CAST(SIZE * PRICE AS NUMERIC(15, 5)) AS TOTAL
FROM TNAME
Regarding the first question, the number of decimals, there is nothing wrong. It's the basic, everyday multiplication we learn at school: Multiplying two decimal numbers produces a number with as many decimal digits as the sum of decimal digits of the operands. The number of integer digits can be up to the sum of integer digits of the operands.
Multiplying 10.11 by 12.13 produces 122.6343. It would be VERY awkward if SQL Server broke this basic rule and arbitrarily truncated the result.
As a result, when you try to store the product in a column that accepts fewer digits, you get an overflow error. SQL Server won't change the number of digits automatically because there is no way to decide the correct action.
There are a lot of ways you can handle this, depending on the loss of precision you are willing to suffer:
Truncate the extra digits, ie throw them away, accepting up to a unit loss. This can become a LOT of money if you store totals.
Round to the desired number of digits. Sounds intuitive, but what about half-way values, ie 0.00005 in your case? Should it be 0.0001 or 0.0000? So we have
Rounding up, where 0.5 becomes 1, resulting in up to .5 loss per entry
Down, when it becomes 0, with the same loss
Round to even or odd, where you round to the nearest odd or even number, which on average produces minimal loss. While this sounds weird, it is the standard defined in IEEE 754. It's also called banker's rounding because it's used in bookkeeping to minimize losses due to truncation.
If you want to store fewer digits you need to decide whether you need to truncate the extra digits or how to round the number, then do it yourself in code.
In your case, you can use CAST to a numeric of the desired precision. This will perform rounding half up, where 0.00005 becomes 0.0001, eg:
INSERT INTO TNAME2(SIZE, PRICE, TOTAL)
SELECT
SIZE, PRICE, CAST(SIZE * PRICE as numeric(14,5)) AS TOTAL
FROM
TNAME
SQLFiddle here
This will work, assuming the number of digits doesn't exceed 14, otherwise you will have to change the type of your table field.
If you want some other kind of rounding in SQL, you will have to create your own function.
Got below useful link.
Multiplication of numerics
As per this link you can try as query as below
SELECT SIZE,
PRICE,
CAST(SIZE*PRICE AS numeric(28,5))AS TOTAL
FROM TNAME
Try this
SELECT SIZE,PRICE,CONVERT(numeric(14,5), SIZE*PRICE) AS TOTAL
FROM TNAME
Write the same query in insert, it must work

How can I trim the end of a money data type in sql

Say I have a column that is a money data type in a table, $53125, and I want to update the table's 'sales' column, so that it would instead be $53 for this cell (as an example). Is this possible?
In mysql, the syntax looks like this
UPDATE orders
SET sales = CONCAT("$", FLOOR(sales/1000))
Decimal data types, only serve floating point numbers. To convert to currency, you would have to use the CONCAT method.
To round down to the nearest 1,000, you use the floor method.