Need help in inserting values into ORCL 11g table - sql

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.

Related

SQL - split numeric into 2 columns?

I am trying to split some numeric keys in my table into separate columns (to help save space in SSAS, lower cardinality)
My data looks like the below..
LeadKey
1
2
3
5522
83746623
I want to split these into 2 columns... with 4 digits in each column. (where applicable, as anything 1>9999 won't have anything populated in the 2nd column)
So an example output of the above would be the below..
LeadKey Split1 Split2
1 1
2 2
35566 3556 6
5522 5522
83746623 8374 6623
How could I achieve this? I have split columns easily before using substring and a known character.. but never had to do a split like this. Does anyone have an approach to handle this?
Here is a solution in case you have the LeadKey numbers as int.
select LeadKey
,left(LeadKey, 4) Split1
,right(LeadKey, case when len(LeadKey)-4 < 0 then 0 else len(LeadKey)-4 end) Split2
from t
LeadKey
Split1
Split2
1
1
2
2
35566
3556
6
5522
5522
83746623
8374
6623
Fiddle
In this example, I used left for the Split1, and show the values past the 4th position for the Split2:
I've included a testing temporary table to hold our the testing values.
Feel free to adjust the code to work with your situation.
DECLARE #thelist TABLE
(
LeadKey int
);
INSERT INTO #thelist (LeadKey)
select 1 union all
select 2 union all
select 35566 union all
select 5522 union all
select 83746623
select cast(x1.LeadKey as varchar(19)),
Left(x1.LeadKey, 4) as 'Split1',
(case when len(x1.LeadKey) > 4 then right(x1.LeadKey, len(x1.LeadKey) - 4)
else '' end
) as 'Split2'
from #thelist as x1

APEX Oracle Compare Two Fields (varchar2 )

I want to compare two varchar2 fields and based on the percentage similarity to get this percentage as a result in my function, and the ID of this record from this table.
I have the table (SYMPTOMS), I also have the field Symptom_Descr (VARCHAR2) of this table and the variable v_symptom (varchar2) and I want to compare this variable with this field.
For example, this is my table:
The variable that I want to compare is:
'flashes the room lights 5 times'
I want as a result=
id
1
0%
2
0%
3
90%
Another example if the variable is 'washes her hands 7 times':
id
1
80%
2
0%
3
10%
The above percentages are not exact.
If the above cannot be done, then what can I do to find the similarities?
You can use the UTL_MATCH package:
SELECT id,
UTL_MATCH.EDIT_DISTANCE_SIMILARITY(
symptom_descr,
'flashes the room lights 5 times'
) AS ed_similarity,
UTL_MATCH.JARO_WINKLER_SIMILARITY(
symptom_descr,
'flashes the room lights 5 times'
) AS jw_similarity
FROM symptoms;
Which, for the sample data:
CREATE TABLE symptoms (id, symptom_descr) AS
SELECT 1, 'washes his hands constantly' FROM DUAL UNION ALL
SELECT 2, 'checks several times if he turned off the water heater' FROM DUAL UNION ALL
SELECT 3, 'flashes the room lights too many times' FROM DUAL;
Outputs:
ID
ED_SIMILARITY
JW_SIMILARITY
1
30
62
2
25
62
3
79
93
db<>fiddle here

Finding a value in multiple columns in Oracle table

I have a table like below
ID NUMBER 1 NUMBER 2 NUMBER 3 LOC
1-14H-4950 0616167 4233243 CA
A-522355 1234567 TN
A-522357 9876543 WY
A-522371 1112223 WA
A-522423 1234567 2345678 1234567 NJ
A-A-522427 9876543 6249853 6249853 NJ
and I have a bunch of values (1234567, 9876543, 0616167, 1112223, 999999...etc) which will be used in where clause, if a value from where clause found in one of the three Number columns (Number 1 or Number 2 Number 3) then I will have to write that to output1 (its like VLOOKUP of Excel).
If the value is found in more than one of the three columns then it will be different output2 with a flag as MultipleMatches. If the value is not found in any of the three columns then it should be in Output2 with flag as No Match. I tried using self join and or clauses, but not able to get what I want.
I want to write the SQL to generate both outputs. Outputs will include all the columns from the above table. For eg:
Output 1 from above sample data will look like
ID NUMBER 1 NUMBER 2 NUMBER 3 LOC
1-14H-4950 0616167 4233243 CA
A-522371 1112223 WA
Output 2 will be like:
ID NUMBER 1 NUMBER 2 NUMBER 3 LOC Flag
A-522423 1234567 2345678 1234567 NJ Multiple Match
A-A-522427 9876543 6249853 6249853 NJ Multiple Match
1234 No Match
I want to write the SQL to generate both outputs.
One SELECT operator cannot produce two output sets.
The main question is, why split the output when that the difference is only in the FLAG column? If you really need two different output of the result, then you can do this:
(Rightly) create a common cursor for the query, where the FLAG column will be calculated and split the output screens already in the UI.
drop table test_dt;
create table test_dt as
select '1-14h-4950' id,null num1,616167 num2,4233243 num3,'ca' loc from dual
union all
select 'a-522355',null ,1234567,null,'tn' from dual union all
select 'a-522357',null ,9876543,null,'wy' from dual union all
select 'a-522371',null ,1112223,null,'wa' from dual union all
select 'a-522423',1234567,2345678,1234567,'nj' from dual union all
select 'a3-522423',null,null,null,'nj' from dual union all
select 'a-a-522427',9876543,6249853,6249853,'nj' from dual;
--
select
d.*,
case when t.cc_ndv=0 and t.cc_null=3 then 'Not matching'
when t.cc_ndv=(3-t.cc_null) then 'Once'
else 'Multiplay match'
end flag
--t.cc_ndv,
--t.cc_null
from test_dt d ,lateral(
select
count(distinct case level when 1 then num1
when 2 then num2
when 3 then num3
end ) cc_ndv,
count(distinct case level when 1 then nvl2(num1,null,1)
when 2 then nvl2(num2,null,2)
when 3 then nvl2(num3,null,3)
end ) cc_null
from dual connect by level<=3 and sys_guid()is not null
) t;
Or
create a procedure(see to dbms_sql.return_result) that returns a some data sets.
Process these data of cursors / datasets separately.

SQL to get all number that have more than 3 digits after the decimal point

I would like to get all number that have more than 3 digits after the decimal point.
For example, I have a table called ARTICLE that have two columns: name (varchar type) and price (number).
I would like to get all the record stored in table ARTICLE where the price column value have more than 3 numbers after the decimal point.
For example, ARTICLE.price value equal to 12.9584 or 45.874521 will be returned since they have more than 3 numbers after the decimal point.
How could I achieve this please?
I tried this request but it is not correct:
select name, price
from ARTICLE
where length(TO_CHAR(price)) > 7;
Thanks
Use ROUND function - you are looking for number that don't equal a rounded value to three digits.
Example - you test data
select round(2/3,rownum) price from dual connect by level <= 5
PRICE
----------
,7
,67
,667
,6667
,66667
Query to get numbers with more that 3 digits after the decimal point
with dt as (
select round(2/3,rownum) price from dual connect by level <= 5
)
select price from dt
where price != round(price,3)
PRICE
----------
,6667
,66667
Coming to a similar solution than #Krzysztof:
CREATE TABLE article (name VARCHAR2(10), price NUMBER);
INSERT INTO article VALUES ('a', 12.9584);
INSERT INTO article VALUES ('b', 45.874521);
INSERT INTO article VALUES ('c', 0.123);
SELECT * FROM article WHERE ABS(price - TRUNC(price,3)) > 0;
NAME PRICE
a 12,9584
b 45,874521
You can operate on numbers only:
where trunc(price * 1000) - price * 1000 <> 0
I don't have a table to test this on, but you might be able to use:
Select Name, Price
From Article
Where Price like '%#.###%'
This would say that there has to be at least 1 number before the decimal, and at least 3 after the decimal. More info on the wildcard characters below:
https://www.w3schools.com/sql/sql_wildcards.asp
Hopefully this helps!

Oracle need to remove decimal point

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>