Oracle need to remove decimal point - sql

Simple and quick question
If I have column have values in decimals
number
10.20
13.4000
15.987
i Want to remove the decimal from display the output without decimal
number
1020
134000
15987
I have tried
select replace(number, '.','') from table
I got the result but is there any other way to solve it.

Apparently, values you're dealing with are strings, aren't they? Otherwise, you wouldn't have all those trailing zeros.
Anyway, if it happens that these are numbers after all, a little bit of mathematics might produce the desired result. For example:
SQL> with test (num) as
2 (select 10.201 from dual union
3 select 13.4000 from dual union
4 select 15.987 from dual
5 )
6 select num,
7 num * power(10, to_number(length(to_char(num - trunc(num))) - 1)) result
8 from test;
NUM RESULT
---------- ----------
10,201 10201
13,4 134
15,987 15987
SQL>

Related

How to add decimal places to numbers without them and add decimals to those with only one decimal column

So i have a column that is number by type, there are values in there with numbers like 8, 15.0, 89.1 or null. I need to add a decimal spot to them so they would look like 8.00, 15.00, 89.10 and the nulls replaced with 0.00.( there are hundreds of number values not just the 4 examples) I figured I needed to do an update with a case, the null part is simple enough
update table
set cost = case
when null then 0.00
not sure how to tackle the other three situations, any help is much appreciated !!
So i have a column that is number by type
To me, it looks like a presentation issue, not storage. Justin tried to convince you that you don't have to do anything about it, I suggest you re-read what he said.
Table looks like this:
SQL> create table test (col) as
2 select 8 from dual union all
3 select 15.0 from dual union all
4 select 89.1 from dual union all
5 select null from dual; --> only NULL should be replaced by 0
Table created.
SQL> update test set col = 0 where col is null;
1 row updated.
SQL>
If you don't do anything, this is the result:
SQL> select * from test;
COL
----------
8
15
89,1
0
SQL>
As of presentation: it depends on a tool you use. For example: if it were SQL*Plus, you could format the column as
SQL> column col format 90D00
SQL> select * from test;
COL
------
8,00
15,00
89,10
0,00
SQL>
Comma is a decimal character in my database; change it to a dot:
SQL> alter session set nls_numeric_characters = '.,';
Session altered.
SQL> select * from test;
COL
------
8.00
15.00
89.10
0.00
SQL>
Or, in any tool, use the TO_CHAR function with appropriate format mask:
SQL> select col, to_char(col, '90D00', 'nls_numeric_characters = ''.,''') result from test;
COL RESULT
---------- ------
8 8.00
15 15.00
89,1 89.10
0 0.00
SQL>
Or, if it is some GUI tool (be it Oracle Forms, Reports, Apex, ...), it contains the Format mask property you should use for the same purpose - presentation - and put 90D00 into it to format value displayed to end users.
Therefore, once again: there's nothing wrong with values stored in that column; it is just about the way users will see them.

Oracle Insert Value Into Middle of Existing Value

This is similar to my previous question. I have the following partial docket numbers:
docket_number
-------------
2012JV592
2016DR138
2018JV84
If the docket number is less than 10 digits, then I need to insert 0's after the second letter until the lenth is 10 digits. Updated docket numbers would look like this.
docket_number
-------------
2012JV0592
2016DR0138
2018JV0084
One option might be to
split docket_number into two parts: first part contains digits and letters, the second contains the trailing number
result is concatenation of the first part and the second part left padded with zeroes up to total length of 10 characters
SQL> with test (docket_number) as
2 (select '2012JV592' from dual union all
3 select '2016DR138' from dual union all
4 select '2018JV84' from dual
5 ),
6 temp as
7 (select docket_number,
8 regexp_substr(docket_number, '[[:digit:]]+[[:alpha:]]+') part1,
9 regexp_substr(docket_number, '[[:digit:]]+$') part2
10 from test
11 )
12 select case when length(docket_number) < 10 then
13 part1 || lpad(part2, 10 - length(part1), '0')
14 else docket_number
15 end result
16 from temp;
RESULT
--------------------------------------------------------------------------------
2012JV0592
2016DR0138
2018JV0084
SQL>
How to update rows in a table? By using such a SELECT in UPDATE, e.g.
SQL> select * from test;
DOCKET_NUM
----------
2012JV592
2016DR138
2018JV84
SQL> update test a set
2 a.docket_number =
3 (with temp as
4 (select b.docket_number,
5 regexp_substr(b.docket_number, '[[:digit:]]+[[:alpha:]]+') part1,
6 regexp_substr(b.docket_number, '[[:digit:]]+$') part2
7 from test b
8 )
9 select case when length(t.docket_number) < 10 then
10 t.part1 || lpad(t.part2, 10 - length(t.part1), '0')
11 else docket_number
12 end
13 from temp t
14 where t.docket_number = a.docket_number
15 );
3 rows updated.
SQL> select * from test;
DOCKET_NUM
----------
2012JV0592
2016DR0138
2018JV0084
SQL>
You can split the data into three parts as digit group1, letters group, and digit group2 by using regexp_substr() functions, and lpad() function in order to add zeroes just before the second digit group, and then concatenate them directly by using || operators, assuming that you have the same data model for the whole table,
UPDATE t
SET docket_number = regexp_substr(docket_number,'[[:digit:]]+')||
regexp_substr(docket_number,'[[:alpha:]]+')||
lpad('0',10-length(docket_number),'0')||
regexp_substr(docket_number,'[[:digit:]]+$')
Demo
Is it the case that your docket_number should always follow the format 4 digits (year?) followed by 2 letters followed by 4 digits. Then simple sub-string of the docket_number and subsequent re-concatenation is sufficient.
select docket_number
, substr(docket_number,1,6) || lpad(nvl(substr(docket_number,7),'0'),4,'0')
from test_dn
where length(docket_number) < 10
order by docket_number;
and for update:
update test_dn
set docket_number = substr(docket_number,1,6) || lpad(nvl(substr(docket_number,7),'0'),4,'0')
where length(docket_number) < 10;
If the format holds true then, depending on table size, this could be significantly faster as regular expressions are relative slow.

FETCH DATA BASED ON PARTICULAR STRING

I need to fetch records based on particular type(FFRT-TR= ) and then replace it. For example below are the record types
20017546 FFRT-TR= 3456
TT:SX 2398 FFRT-TR=6532
I need to fetch records which contains FFRT-TR= and then replace the whole the of FFRT-TR=3456 Required Output based on the above examples: 20017546(for 1st example) 2398(for 2nd example)
Please help. Thanks in advance
Something like this? Oracle-ish (you didn't specify the database you use), but - hopefully - you'll be able to rewrite it if necessary.
SQL> with test (col) as
2 (select '20017546 FFRT-TR= 3456' from dual union
3 select 'TT:SX 2398 FFRT-TR=6532' from dual
4 )
5 select
6 col,
7 replace(regexp_substr(col, '\d+ FFRT-TR='), 'FFRT-TR=', '') result
8 from test;
COL RESULT
----------------------- ----------------------------------------------------
20017546 FFRT-TR= 3456 20017546
TT:SX 2398 FFRT-TR=6532 2398
SQL>

regular expression to get all numbers except in a range

I want to get a list ip addresses whose last 3 digits don't fall in the range 0 to 200. I tried using REGEXP_LIKE as below. But it is giving me wrong result.
select * from ip_data
where REGEXP_LIKE(substr(ip_address,instr(ip_address,'.',1,3)+1),'[^0-200]');
It seems to have matched each digits with 0-200 numbers individually.
I want to use only REGEXP_LIKE as I've to take the range from another table where it is stored in the format [0-200].
Any suggestions would be of great help.
Using REGEXP_SUBSTR:
SQL> WITH DATA AS(
2 SELECT '127.0.0.1' ip FROM dual UNION ALL
3 SELECT '127.0.0.201' ip FROM dual
4 )
5 SELECT * FROM DATA
6 WHERE REGEXP_SUBSTR(ip,'[[:digit:]]{1,3}',1, 4)
7 NOT BETWEEN 0 AND 200
8 /
IP
-----------
127.0.0.201
SQL>
Using simple SUBSTR:
SQL> WITH DATA AS(
2 SELECT '127.0.0.1' ip FROM dual UNION ALL
3 SELECT '127.0.0.201' ip FROM dual
4 )
5 SELECT * FROM DATA
6 WHERE to_number(substr(ip,instr(ip,'.',1,3)+1))
7 NOT BETWEEN 0 AND 200
8 /
IP
-----------
127.0.0.201
SQL>
I would go with the simple SUBSTR approach since it is less resource consuming, less CPU utilization, thus better performance.
You don't need regular expression for that:
to_number(substr(ip_address,instr(ip_address,'.',1,3)+1)) not between 0 and 200
Something like this should works:
select ip_address from ip_data
where NOT REGEXP_LIKE(ip_address,'\.(([0-9])|([1-9][0-9])|([1][0-9][0-9])|(200))$');

Need help in inserting values into ORCL 11g table

This is my insert into statement:
INSERT INTO PRODUCT
VALUES
('PROD010', 'Kiwi milk tea', 'A milk tea that made from kiwi powder and other ingredients.', 4.50, 5.00);
But,what appear on the screen are PROD010, Kiwi milk tea, A milk tea that made from kiwi powder and other ingredients, 4.5 and 5
All zeros of 4.50 and 5.00 are disappear.
So, what should I do now so that all zeros can be displayed??
Codes of PRODUCT table:
CREATE TABLE PRODUCT(
PROD_ID VARCHAR(10) NOT NULL,
PROD_NAME VARCHAR(30),
PROD_DESC VARCHAR(70),
R_UNIT_PRICE NUMBER(3,2),
L_UNIT_PRICE NUMBER(3,2),
primary key (PROD_ID)
);
There's nothing you can change in the table to make the client display trailing, insignificant, zeros. (At least while keeping it as a number; don't even consider storing it as a string). The numeric value is stored in an efficient internal format. When the client retrieves the value it is converted into the client's natice numeric format, and the client decides how it should be displayed.
To show zeros in a client like SQL*Plus, including 0.00, you can retrieve it as a string:
select prod_id, prod_name, prod_desc,
to_char(r_unit_price, '0.00') as r_unit_price,
to_char(l_unit_price, '0.00') as l_unit_price
from product;
SQL Fiddle demo.
You will need to do that in each query where it matters, unless your client application does its own formatting. When you are using the value in a calculation leave it as a number while it's being used, and apply the format model to the final disolayed result - otherwise you'll have pointless implicit conversions to and from strings, and the potential for errors.
Your data type is very restrictive - you can't have a value of 10 or above. That might be what you want, but review the precision and scale information Mihai linked to.
select num, length(num) len, instr(num,separator) dot
,case when instr(num,separator) > 0 then length(num) - instr(num,separator) else 0 end as dot2
,case when instr(num,separator) > 0 then rpad(num,instr(num,separator)+2,0) else num||separator||'00' end as num2
from ( select ',' as separator from dual ) sep,
(
select 1.21 as num from dual union all
select 1.2 as num from dual union all
select 9 as num from dual union all
select 11.456 as num from dual union all
select 341.2 as num from dual
);
NUM LEN DOT DOT2 NUM2
1,21 4 2 2 1,21
1,2 3 2 1 1,20
9 1 0 0 9,00
11,456 6 3 3 11,45
341,2 5 4 1 341,20
NUM2 is the answer.
Change separator do comma or dot, depending on Your environment.