Insert same values into table with a different values from other table - sql

I am trying to insert the same value into all rows except for a different value being imported from another table. I am doing it on oracle database
I have tried the following :
insert into table
(ID, version, other_id, value3,value4,value5,value6,value7,value8,value9)
VALUES
((select MAX(ID)+1 from table), '0', '5', '0', '1',
select name from table2,
select name from table2, '11', '14', '50');
all the values are the same except for the name from table2 will be different in each entry.
Any hint on how to insert all of them at once instead of having to do each one seprate?

You can do it, certainly, but not the way you put it (as you already know).
I'd suggest you NOT to use max + 1 because it just won't work properly, especially in a multi-user environment. Use a sequence instead.
Here's an example: insert into t1 values based on t2.
Sample tables:
SQL> DESC t1;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
VERSION NUMBER
JOB VARCHAR2(10)
SQL> DESC t2;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
JOB VARCHAR2(10)
SQL> SELECT * FROM t1;
no rows selected
SQL> SELECT * FROM t2;
ID JOB
---------- ----------
1 CLERK
2 MANAGER
SQL>
A sequence:
SQL> CREATE SEQUENCE seqt;
Sequence created.
Insert statement:
SQL> INSERT INTO t1 (id, version, job)
2 SELECT seqt.NEXTVAL, '0', t2.job FROM t2;
2 rows created.
Result:
SQL> SELECT * FROM t1;
ID VERSION JOB
---------- ---------- ----------
1 0 CLERK
2 0 MANAGER
SQL>

my first attempt would be to generate the insert statements using concatenate; and for ID, use max_id + rownumber;
how many rows does table2 have? if not millions, concatenate should be easy approach.

Related

Oracle SQL select greatest value of the result of two different select statements

I'm running select statements in a loop with a cursor to collect data from different tables;
Quick (NOT WORKING) example;
select DISTINCT(ordernr) from orders
INSERT INTO newtable (select Crs.ordernr as ordernr, value1 as value from table2 where table2.ordernr = Crs.ordernr );
INSERT INTO newtable (select Crs.ordernr as ordernr, value2 as value from table3 where tabel3.ordernr=Crs.ordernr ;
)
LOOP
END LOOP;
END;
What I could like is just one insert statement which insert just the biggest value of boths select statements.
I've tried to work with greatest function in my loop but i'm running stuck. Both datatypes are the same for value1 and value2
insert into newtable(select crs.ordernr as ordernr, greatest
(
select value1 as value from table1 where condition=1, select value2 as value from table2 where condition=1)
)
);
Is it possible with a select case or other way to return only one value based on conditions? For example the biggest value of value1 or value2?
You can use the greatest function and provide subqueries to it, but - follow the syntax, i.e. enclose each of them (select statements) into its own parenthesis.
Something like this:
SQL> select greatest ( (select max(sal) from emp where job = 'CLERK'),
2 (select max(sal) from emp where job = 'ANALYST')
3 ) greatest_salary
4 from dual;
GREATEST_SALARY
---------------
3450
SQL>
I have no idea what is this:
insert into newtable(select crs.ordernr as ordernr
-----------------------------
supposed to do; what is crs? Where's the from clause?
From Oracle 12, you can use:
INSERT INTO newtable (ordernr, value)
SELECT *
FROM (
SELECT Crs.ordernr as ordernr,
value1 as value
FROM table2
WHERE table2.ordernr = Crs.ordernr
UNION ALL
SELECT Crs.ordernr,
value2
FROM table3
WHERE table3.ordernr=Crs.ordernr
)
ORDER BY value DESC
FETCH FIRST ROW ONLY;
This will mean that if you extend the query to extract more columns and you want the highest of one column and the corresponding values of the other columns then the values will all come from that one row with the highest value.
db<>fiddle here

How to de-duplicate millions of records in oracle?

I have a table (with one column called Id) and it has about 10 millions records. Some of these Ids are duplicate and I need to transfer unique Ids into another table (which will also have same one column). I am looking for a sql which can do it and quickest of performance.
10million won't be an issue for the database. Here's an example of that just on my laptop
SQL> create table t as
2 select mod(rownum,10000000) x
3 from
4 ( select 1 from dual connect by level <= 11000 ),
5 ( select 1 from dual connect by level <= 1100 );
Table created.
SQL>
SQL> select count(*) from t;
COUNT(*)
----------
12100000
SQL> set timing on
SQL> create table t1
2 as select distinct x from t;
Table created.
Elapsed: 00:00:03.96
SQL> select count(*) from t1;
COUNT(*)
----------
10000000
Elapsed: 00:00:00.23
So expect around 3-4 seconds to get the unique list.

update one table with data from another using derived key value

Table 1:
id name desc
------------------
1 a abc
2 b def
3 c adf
Table 2:
name desc
------------
x 123
y 345
How do I run an sql update query that can update Table 1 with Table 2's name and desc using the id of table 1 and rownum in table2? It's okay to assume that rownum in table2 is the same as id of table 1. So the end result I would get is
Table 1:
id name desc
------------------
1 x 123
2 y 345
3 c adf
Below are scripts for table creation and record insertion
create table table1 (
id number,
name varchar2(10),
desc_ varchar2(10)
);
create table table2 (
name varchar2(10),
desc_ varchar2(10)
);
insert into table1 values(1, 'a', 'abc');
insert into table1 values(2, 'b', 'def');
insert into table1 values(3, 'c', 'ghi');
insert into table2 values( 'x', '123');
insert into table2 values( 'y', '456');
Credits to "update one table with data from another"
There is no such thing as "rownum" in a table. SQL tables represent unordered sets, so there is no ordering without an ordering column.
Oracle does provide rowid as a built-in column identifier. This is not the same as rownum and is not guaranteed to be in order.
You can use rownum, but the value is not guarantee to have any particular meaning and might change between runs:
update table1
set (name, desc) = (select name, desc
from (select t2.*, rownum as seqnum
from table2
) t2
where seqnum = table1.id
)
where id <= (select count(*) from table2);

Oracle Insert using FLASHBACK Query

I have two identical schemas, on different databases connected via Database Link.
Schema_1: Source Schema. **Rows being inserted at rapid rate.**
Schema_2: Target Schema.
Rows being inserted into Schema_1 (source schema) at rapid rate.
I am running a SQL in Source Schema as follows:
Insert into Table_1#DB_LINK select * from Table_1
This statement takes several minutes.
Now I change the statement as follows ( using flashback query )
Insert into Table_1#DB_LINK select * Table_1 as of timestamp to_timestamp ( to_timestamp ( date ));
This query completes in few seconds.
Why such huge difference ?
In your flashback query you are selecting the rows which were inserted exactly on 05/01/2017 10:00:00. But in your non-flashback query you are selecting all the rows inserted in the table.
Simple demonstration:
SQL> create table t1(id number, name varchar2(20));
Table created.
SQL> insert into t1 values(1, 'joe');
1 row created.
SQL> insert into t1 values(2, 'jay');
1 row created.
SQL> commit;
Commit complete.
SQL> insert into t1 values(3, 'john');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from t1;
ID NAME
---------- --------------------
1 joe
2 jay
3 john
SQL> select * from t1 as of timestamp to_timestamp('02-MAY-17 11:00','DD-MON-RR HH24:MI');
ID NAME
---------- --------------------
1 joe
My first query, select * from t1;, is identical to your non-flashback query which selects all the rows from the table.
And my second query, select * from t1 as of timestamp to_timestamp('02-MAY-17 11:00','DD-MON-RR HH24:MI'); is similar to your flashback query, which selects only one rows.
Of course inserting one row is faster than inserting three rows.

trying to set column type in a view

I have this in a view query
(SELECT CAST(COUNT( *) AS NUMBER(10))
FROM other_table ibl
WHERE ibl.fk_id = my_table.id
) AS my_column
However Oracle still reports the column as type number with no size.
Is there any way around this?
I want it to be number(10)
db version is 11.2
It appears that you've just put the CAST in the wrong place. Your CAST would need to wrap your inline subquery
In this example, col2 is how it appears you are defining the column currently. col1 shows how it would need to be defined.
SQL> ed
Wrote file afiedt.buf
1 create or replace view vw_foo
2 as
3 select cast( (select count(*) from dual) as number(10) ) col1,
4 (select cast( count(*) as number(10)) from dual) col2
5* from dual
SQL> /
View created.
SQL> desc vw_foo
Name Null? Type
----------------------------------------- -------- ----------------------------
COL1 NUMBER(10)
COL2 NUMBER
What you're trying to do should work just fine, so your problem must originate somewhere else. Below is a script that I used to test this.
CREATE Table table1 (no1 NUMBER);
INSERT INTO table1 VALUES(123);
DESC table1;
CREATE VIEW view1 AS
SELECT CAST(no1 AS NUMBER(10)) AS no2 FROM table1;
DESC view1;