Converting (Casting) column to make operations in Oracle - sql

Here's what i'm having trouble with. I have a table where i have the column weight, the data in this column is varchar2, example: 60 kg.
When i try to make a WHERE condition asking to retrieve everything below 60 kg, it doesn't give me the wanted results.
I tried to convert using to_number but it's not working and giving me error "Invalid Number". I also tried to cut the kg with SUBSTR and convert, and doesn't work as well.
Any suggestions?
Thanks in advance.

You can extract leading digits and convert that to a number:
select to_number(regexp_substr(weight, '^[0-9]*'))
from t;
The regular expression is starting from the beginning of the string (the ^) and extracting digits. The * is for any number of digits. Regular expression match is "greedy" by default, meaning that it will keep matching as many digits in a row as there are.
If you have decimal places or negative values, this might be a tad bit more complicated.

Related

How to remove trailing zeroes in snowflake?

I have a column that is in INT type. I want to remove all the trailing zeroes and only have the number. The example below, should follow be: 3,10,20,20. I cannot have the 4 zeroes at the end.
Is there a way to do this?
You could try casting your numeric data to integer, e.g.
SELECT AS_INTEGER(col) AS col
FROM yourTable;
the 3dp is how floating point numbers print, thus you can cast to number SELECT column_name::number FROM table
If your data is a string/varient type, and not all values stored in your column always casts cleanly, in Snowflake you can hit error, with the TO_NUMBER or ::number forms, thus [TRY_TO_NUMBER][2] form should be used.

SQL Server query - Correction in syntax

Could you please help me to correct the syntax ?
I have to write below code in SQL server.
This is working perfectly fine in Oracle database.
Select to_number(substr((((END_TS - BEGIN_TS)*(24*60*60))),1,10)) AS EXECUTION_TIME
from TABLE B
Also END_TS and BEGIN_TS are of datetime datatypes.
In SQL Server math can not be performed directly on dates, as it can in Oracle. You need to apply a datediff function to calculate the difference before you manipulate it:
select convert(numeric(10,9),left(datediff(second,begin_ts,end_ts)/(24.0*60*60),10)) from table;
Note that the expression in the divisor needs to have a floating point number in it (hence the ".0") otherwise the result is rounded to an integer.
After performing the date calculation, the left function is the equivalent of the substring in Oracle. It converts to a varchar then takes the first 10 characters. Convert then returns to a numeric, which is the equivalent of Oracle's variable-length number. It is necessary to tell convert that you expect digits after the decimal, otherwise it will round.
The substring for the first 10 characters has a bad smell, I would leave it out. This snippet does the calculation without restricting to the first ten characters.
select datediff(second,begin_ts,end_ts)/(24.0*60*60) from table;
Also note that the Oracle version provides fractional dates. If you only wanted the whole day then use "day" as the datepart parameter to datediff.

Oracle - select * where column>5

I am trying to do a comparison based on a column. Let's say, if column>5.
select * where column>5
The column contains non digits. I thought Oracle allows one to compare strings (like Java).
Apparently this is not allowed.
ORA-01722: invalid number
01722. 00000 - "invalid number"
Is there a way to do comparisons with non numeric fields?
Thanks
Yes, you have to put the 5 in quotes :
select * from table where column > '5'
To shed a bit more light on why it doesn't work.
When using a number literal 5 instead of a character literal '5' Oracle does an implicit data type conversion and tries to convert all values in your table to a number. That's why you get that error.
You should never rely on implicit data type conversion. That is bound to give you trouble sometime.
Now if you correctly compare a character literal ('5') against a character column, no data type conversion is needed and no error occurs.
However: if you expect Oracle to actually do a numeric comparison then you are mistaken. Character string are based on ASCII values. Therefor the (character) value '10' is lower than the (character) value '2' because the first character '1' is ranked lower than '2'.
If the column is varchar2, then this:
select * from some_table where some_column > 5
... does an implicit conversion of all the column values to numbers, so you're really doing:
select * from some_table where to_number(some_column) > 5
It's the to_number() that's causing the ORA-01722, even though you can't see it, when it hits a value that is not numeric. The function being called on the column value also stops any index being used (oversimplifying a bit).
You can stop it failing, and let it use the index if there is one, by doing where some_column > '5' as other have said, or where some_column > to_char(5). But you need to be careful doing the comparison as it will still be a string comparison, not a numeric one; so '10' will not be seen as > '5'; and your NLS sorting parameters might produce results you aren't expecting. Or more importantly, someone else's NLS parameters - when you put this live for example - might product results you aren't expecting and which don't match the ones you got in your environment. See the documentation for more.
You should use number columns to hold numeric values, date columns to hold dates, etc., and varchar2 only to hold text values.
you can use to_char function
select * from table where column > to_char(5)
You are missing the table:
select * where FROM tablename column>5
But this only works if column is a number. If not, you can't use >.
To compare strings, you can use LIKE or STRCMP(), check examples of them HERE.
As stated by #Gerrat, you can also use > and < but the types of both sides must be compatible (number with number or text with text). To find more about it, check THIS.
Be aware that in text comparison it will compare each character individually so '11' will be < that '2'.

to_number function in sql

i could not understand why following code
SQL>
Select to_number('1234.64', '9999.9') from Dual;
returns this number 1234.6?is it something like rounding ,truncation or?please help me to understand this code,i know to_number functions,i have used many times this code for simple chars,but here it is not clear anything
This looks a lot like Oracle, but I suspect that the result would be similar in any SQL that used to_number.
The to_number function takes two arguments: the string to be converted to a number, and the format string for the conversion.
In the example, '12345.64' is the string to be converted, while '9999.9' is the format string. In this format string, a 9 stands for a digit while a . stands for the decimal point.
So the function is asking to convert the string '12345.64' to a number with up to 4 digits to the right of the decimal point, and only 1 digit after the decimal point.
The second argument is optional - under normal circumstances, I would omit it.
You should use
SELECT to_number('1234.64', '9999.99') from Dual;
Your mask tells engine you want just one decimal, so number gets rounded.
If you want to get exact number, don't specify any mask:
SELECT to_number('1234.64') from Dual;

format decimals and comma to numbers retrieved

I have a column in my table which showing an amount. The amount is varying from one column to another and they are more than 15 digits.
What is the best way to format the number to show commas and decimal points?
My query is
select amount from ccamounts
How can I format the number
205511892078
to show as
205,511,892,078
and if there is a radix point it will also appear.
I believe you can use TO_CHAR to do this, the issue is that this is just a formatting function within SQL. It requires that your number is always going to be in the same format.
taking the example above you could do
TO_CHAR('205511892078', '999,999,999,999')
and this would format the number as you have specified, with a decimal place this can be done aswell but the decimal needs to be specified:
TO_CHAR('20551189207842', '999,999,999,999.99')
which would give you 205,511,892,078.42
I think if the field length is going to vary sql will just ignore anything that doesn't fit into the format string (It's a mask). Perhaps you want to consider formatting the number in this case on whichever front end you may be using?
I would format the number in the UI / Reporting tool / Presentation layer not Oracle
but if you MUST format it in oracle try:
SELECT
CASE WHEN INSTR( TO_CHAR(205511892078),'.')>0 THEN
TO_CHAR(205511892078 ,'999,999,999,999.99')
ELSE
TO_CHAR(205511892078 ,'999,999,999,999')
END
FROM DUAL
this will return the number as a string.
declare #d3 decimal (10, 2)
set #d3 = 12309809.5494
SELECT convert(varchar(15),cast(CAST(ROUND(#d3,2,1) AS DECIMAL (30,2)) as money),1) as Value
SELECT CAST(ROUND(convert(varchar(30), cast(#d3 as money),2),2,1) AS DECIMAL (30,2)) as Value
Output:
12,309,809.55
12309809.55