Oracle, inserting rows by using Max+1 of the existing field - sql

Hi I am pretty new to oracle.
I have to insert a row using a value of (max + 1) from the existing field.
Does anyone has any idea on how to achieve that?

Do you mean like this?
SQL> create table t (col) as (select 4 from dual union all select 9 from dual);
Table created.
SQL> select * from t;
COL
----------
4
9
2 rows selected.
SQL> insert into t values (1 + (select max(col) from t));
1 row created.
SQL> select * from t;
COL
----------
4
9
10
3 rows selected.

Related

How to store both integers and decimals in a column oracle [duplicate]

This question already has answers here:
Does Oracle store trailing zeroes for Number data type?
(3 answers)
Closed 11 months ago.
The community reviewed whether to reopen this question 11 months ago and left it closed:
Original close reason(s) were not resolved
I am trying to create a column (amount) that has both integers and decimals. But the issue is the column always stores the values as integers.
CREATE TABLE payments(payment_id , Status , payment_date , account_id , currency, amount) AS
SELECT '72b30af0-323e-4931-8fcc-2c08ad8d0b19', 'completed', TO_DATE ('01/10/2017','DD/MM/YYYY'), 2291969088, 'GBP', CAST(10.00 AS NUMBER(20,18)) FROM DUAL UNION ALL
SELECT '1b5341c0-508c-450f-a139-bc898f112fed', 'completed', TO_DATE ('12/11/2014','DD/MM/YYYY'), 7851880663, 'USD', CAST(20 AS NUMBER) FROM DUAL UNION ALL
SELECT '4c8eb68d-3085-4500-b735-371bb7e1ac97','submitted', TO_DATE ('03/07/2016','DD/MM/YYYY'), 5326844767, 'USD', CAST(3.000 AS NUMBER) FROM DUAL UNION ALL
SELECT '33825ef2-d0da-4062-a435-b74a25a850ed','failed', TO_DATE ('19/01/2017','DD/MM/YYYY'), 3668657617, 'EUR', CAST(40 AS NUMBER) FROM DUAL UNION ALL
SELECT '45c10898-d668-4ad1-9730-415254f6e085', 'completed', TO_DATE ('10/05/2017','DD/MM/YYYY'), 9040142052, 'GBP', CAST(30.000 AS NUMBER) FROM DUAL
I have tried using Number alone and Number with precision and scale but the result is the same even with the Decimal data type. Not sure what am I doing wrong here?
The table will store the values in a correct way.
Your select is the problem I believe.
select payment_id
, Status
, payment_date
, account_id
, currency
, to_char(amount, '99.999')
from payments;
I have used to_char() functionto format your column when selecting.
Please correct me if I am wrong.
DEMO
Just to expand on answer by #VBoka, providing more thorough example:
the root of your question is basic math. Trailing zeros to the right of the decimal are insignificant. 10 = 10.0 = 10.000000. You are confusing how the value is stored vs how it is displayed by default.
SQL> -- -------- create the tables
SQL> create table my_demo (my_id integer,
2 my_value number(5,2));
Table created.
SQL> -- -------- load tables
SQL> insert into my_demo values (1,10);
1 row created.
SQL> insert into my_demo values (2,10.0);
1 row created.
SQL> insert into my_demo values (3,010.00);
1 row created.
SQL> -- -------- Do the query
SQL> select my_id,
2 my_value,
3 to_char(my_value,'999.999') formatted_value
4 from my_demo
5 order by my_id
6 ;
MY_ID MY_VALUE FORMATTE
---------- ---------- --------
1 10 10.000
2 10 10.000
3 10 10.000
3 rows selected.
And why are you using "CAST(10.00 AS NUMBER"? The 10.00 (without quotes) is already a number. If you were to enclose it in single quotes ("CAST('10.00' AS NUMBER"), then it would be a string that needs to be treated with either CAST or TO_NUMBER.
== new demo for getting just integer values
SQL> -- -------- load tables
SQL> insert into my_demo values (1,10);
1 row created.
SQL> insert into my_demo values (2,10.0);
1 row created.
SQL> insert into my_demo values (3,010.10);
1 row created.
SQL> -- -------- Do the query
SQL> select my_id,
2 my_value,
3 to_char(my_value,'999.999') formatted_value
4 from my_demo
5 order by my_id
6 ;
MY_ID MY_VALUE FORMATTE
---------- ---------- --------
1 10 10.000
2 10 10.000
3 10.1 10.100
3 rows selected.
SQL> --
SQL> select my_id,
2 my_value,
3 to_char(my_value,'999.999') formatted_value
4 from my_demo
5 where my_value = trunc(my_value)
6 order by my_id
7 ;
MY_ID MY_VALUE FORMATTE
---------- ---------- --------
1 10 10.000
2 10 10.000
2 rows selected.

How to use subquery to drop rows from Tab1 which are in Tab2 in Oracle SQL?

I have tables in Oracle SQL like below:
Tab1
ID
-----
1
2
3
Tab2
ID
-----
3
4
5
And I need to take values from Tab1 which are not in Tab2. I made query like below:
select ID
from Tab1
where ID not in (select ID from Tab2)
Above query does not work, how can I change it to achieve result as I need:
ID
---
1
2
I can add that I prefere to use subquery in this problem, how can I do that in Oracle SQL ?
With the MINUS set operator:
SQL> with
2 tab1 (id) as
3 (select 1 from dual union all
4 select 2 from dual union all
5 select 3 from dual
6 ),
7 tab2 (id) as
8 (select 3 from dual union all
9 select 4 from dual union all
10 select 5 from dual
11 )
12 select id from tab1
13 minus
14 select id from tab2;
ID
----------
1
2
SQL>
BTW, query you used (with a subquery) returns correct result; did you mean to say that you prefer NOT to use a subquery?
<snip>
12 select id from tab1
13 where id not in (select id from tab2);
ID
----------
1
2
I tried this code and it worked fine :
select ID
from Table1
where ID not in (select ID from Table2)
You cant DROP rows from a table, but you can DELETE them.
So correcting you title to
How to use subquery to DELETE rows from Tab1 which are in Tab2 in Oracle SQL?
do so:
delete from tab1
where id in (select id from tab2);
1 row deleted.
select * from tab1;
ID
----------
1
2
Do not forget to commit to make the change permanent.

Update Syntax with joins

I am trying to update a column only with the matched condition.
update table1 set col=Match
where id in(select id from
table1,table2 where table1.id=table2.id);
It says sql command not properly ended.
Here's an example which shows what to do (at least, that's what I understood, based on the question and comments you posted).
Test case first:
SQL> create table table1 (id number, criteria varchar2(10));
Table created.
SQL> create table table2 (id number);
Table created.
SQL> insert into table1 (id)
2 select 1 from dual union all
3 select 2 from dual;
2 rows created.
SQL> insert into table2 (id)
2 select 1 from dual;
1 row created.
As you can see, both tables share ID = 1 so we'd expect its table1.criteria to be modified.
Your query:
SQL> update table1 set
2 criteria = 'M1'
3 where id in (select a.id
4 from table1 a join table2 b on a.id = b.id
5 );
1 row updated.
SQL> -- Result
SQL> select * From table1;
ID CRITERIA
---------- ----------
1 M1
2
Alternatively:
SQL> update table1 a set
2 a.criteria = 'M2'
3 where exists (select null
4 from table2 b
5 where b.id = a.id
6 );
1 row updated.
SQL> select * From table1;
ID CRITERIA
---------- ----------
1 M2
2
See if it helps.

rows convert in oracle sql

I have values like below
1,a,b,c
2,d,e
3,f,g
Expected output
1 a
1 b
1 c
2 d
2 e
Can you please help me?
It is very much close to implementing the logic to Split comma delimited strings in a table. The only tricky thing is that you have the row number along with the string itself.
You could use ROWNUM as pseudo column, and then filter out those rows where the leading substr of the string is repeating with the ROWNUM.
For example,
Setup
SQL> CREATE TABLE t(text VARCHAR2(4000));
Table created.
SQL>
SQL> INSERT INTO t SELECT '1,a,b,c' text FROM dual;
1 row created.
SQL> INSERT INTO t SELECT '2,d,e' text FROM dual;
1 row created.
SQL> INSERT INTO t SELECT '3,f,g' text FROM dual;
1 row created.
SQL> COMMIT;
Commit complete.
SQL>
SQL> SELECT * FROM t;
TEXT
----------
1,a,b,c
2,d,e
3,f,g
SQL>
Solution:
SQL> WITH DATA AS(
2 SELECT ROWNUM rn, text FROM t
3 )
4 SELECT *
5 FROM
6 (SELECT rn,
7 trim(regexp_substr(t.text, '[^,]+', 1, lines.COLUMN_VALUE)) text
8 FROM DATA t,
9 TABLE (CAST (MULTISET
10 (SELECT LEVEL FROM dual CONNECT BY LEVEL <= regexp_count(t.text, ',')+1
11 ) AS sys.odciNumberList ) ) lines
12 )
13 WHERE TO_CHAR(rn) <> text
14 ORDER BY rn
15 /
RN TEXT
---------- ----------
1 a
1 b
1 c
2 d
2 e
3 f
3 g
7 rows selected.
SQL>

Get next row value based on returned list of rows

In Oracle, suppose I have a query that returns the following list:
ID Sequence#
12 1
15 3
25 5
All I know in this case is the ID of some row (let's suppose 12), I need to return the ID of a row with the next sequence number which in this case is 3 (id = 15)
How can I do it? I know there's a Oracle function lead, but I wasn't able to successfully impement is.
Yes, you can use lead function to get the next value. Here is an example of how it can be done.
-- sample of data from your question
SQL> with t1(ID, Sequence#) as
2 (
3 select 12, 1 from dual union all
4 select 15, 3 from dual union all
5 select 25, 5 from dual
6 )
7 select *
8 from (select id
9 , sequence#
10 , lead(sequence#) over(order by id) next_sequence#
11 , lead(id) over(order by id) next_id#
12 from t1
13 )
14 where id = 12
15 ;
ID SEQUENCE# NEXT_SEQUENCE# NEXT_ID#
---------- ---------- -------------- ----------
12 1 3 15
SELECT * FROM table1 where ID in (SELECT min(ID) FROM table1 WHERE ID > 12)
Select sequence from my_ table where id=(select min(id) from my_table where sequence> 1)
Replace (1) in the above query with any value that you are searching for its next