Consolidating data from different views into a single sql statement - oracle

I have 4 different view which will give the data in same format. My requirement is to write a single query which will combine data from all these four views with data from another table 'Table1' in such way that if that data in 'Table1' is already present in any of the four view(using some id) then i should not add it to the end result.
For eg: View1, View2, View3,View4 , Table1
My end result should be
(View1+View2+View3+View4+(Table1-(View1+View2+View3+View4))
So the query which i have written is like below one
selet * from view1 union
select * from view2 union
select * from view3 union
select * from view4 union
select * from Table1 where Table1.Id Not in
(select Id from view1 union
select Id from view2 union
select Id from view3 union
select Id from view4 union)
Is there any better ways to frame this query which will improve the performance especially when there is a huge data

Have you tried using distinct? :
select distinct(*) from (
select * from view1 union
select * from view2 union
select * from view3 union
select * from view4 union
select * from Table1);

Actually the not in could be implemented as a minus. On a logical level you can achieve something like:
-- step 1
create or replace view v_basic
as
select *
from view1
union
select *
from view2
union
select *
from view3
union
select *
from view4;
-- step 2
create or replace view v_extension
as
select id
from table1
minus
select id
from v_basic
-- step 3
select *
from v_basic
union
(select *
from table1 t1
where exists (select *
from v_extension e1
where e1.id = t1.id)
Since the union operator distinctly will get the a complete record perhaps you will not have to bother whether an id appears twice. So if the id attribute is the main attribute that tells you whether a record should be retrieved from table1 then you can approach the problem as suggested in then answer. If a whole record holds the distinctive data then you could merge all queries with union operator. In that case =>
select *
from v_basic
union
select *
from table1
... should be enough

Related

equivalent of distinct On in Oracle

How to translate the following query to Oracle SQL, as Oracle doesn't support distinct on()?
select distinct on (t.transaction_id) t.transaction_id as transactionId ,
t.transaction_status as transactionStatus ,
c.customer_id as customerId ,
c.customer_name as customerName,
You can use ANY_VALUE with group by for this:
https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/any_value.html
Example: https://dbfiddle.uk/WUxvjv5J
with t (a,b,c) as (
select 1,10,1 from dual union all
select 1,10,2 from dual union all
select 1,10,3 from dual union all
select 1,20,4 from dual union all
select 1,20,5 from dual union all
select 1,30,7 from dual
)
select a,b,any_value(c)
from t
group by a,b;
Yes, Oracle has a full set of windowing functions you can use for this. The simplest is ROW_NUMBER:
SELECT *
FROM (SELECT x.col1,
x.col2,
x.col3,
ROW_NUMBER() OVER (PARTITION BY x.col1 ORDER BY x.col2 DESC) seq
FROM table x)
WHERE seq = 1
for each distinct col1, it will number the highest col2 value as seq=1, the next highest as seq=2, etc... so you can filter on 1 to get the desired row. You can used as complex ORDER BY logic as you need to pick the row you want. The key thing is that the ORDER BY goes inside the ROW_NUMBER OVER clause along with the distinct (PARTITION BY) definition, not outside in the main query block.

Inserting from a SELECT but changing one column in the middle?

Wondering if there is a way to insert a row into a table from another, with exception of one column in the middle without specifying all the column name? I have 128 columns in the table.
I created a view to store the original records.
CREATE VIEW V_TXN_STG AS
SELECT * FROM TXN_STG;
In table TXN_STG, only one column BRN_CODE is changing.
Something like this doesn't work, because the column is not on the last, but somewhere middle of table structure.
INSERT INTO TXN_STG
SELECT v.*, 'BRN-001' AS BRN_CODE
FROM V_TXN_STG v;
I don't believe that this is possible without explicitly specifying the columns in your select.
first you have to get the columns:
SELECT listagg(column_name, ',') within group (order by column_name) columns
FROM all_tab_columns
WHERE table_name = 'AAA' --Table to insert too
and column_name <> 'B' -- column name you want to exclude
GROUP BY table_name;
Then insert that result on the first row:
insert into aaa(A,C) -- A,C is my result from above,I have excluded column B
select *
from (select 'a' A,'q' AMOUNT,'c' C from dual union all -- my sample data
select 'a','a','c' from dual union all
select 'a','b','c' from dual union all
select 'a','c','c' from dual union all
select 'a','d','c' from dual )
pivot
(
max(1)
for (AMOUNT) -- the column you want to remove from the sample data
IN ()
)
where 1=1
order by A;

Perfomance improvement for hive query

I am using multiple union all and then doing the sum of each column, but this query runs like forever. I have 96GB memory cluster. Please tell me what should i do for performance improvement. Following is my query in hive.
total as
(
select * from
(
select * from table1
union all
select * from table2
union all
select * from table3
union all
select * from table4
union all
select * from table5
union all
select * from table6
union all
select * from table7
union all
select * from table8
union all
select * from table9
)p
)
Select * from
(
select
sum(col_1),
sum(col_2),
sum(col_3),
sum(col_4),
sum(col_5),
sum(col_6),
sum(col_7),
sum(col_8),
sum(col_9),
sum(col_10)
from total
)q;

With clause not working with union

My query result is a union of several queries. I am facing the below error when I use WITH clause within a union. Any ideas why?
select column1 from TABLE_A
union
with abcd as (select * from TABLE_B)
select column2 from TABLE_A A, abcd
where abcd.m_reference = A.m_reference
ORA-32034: unsupported use of WITH clause
32034. 00000 - "unsupported use of WITH clause"
*Cause: Inproper use of WITH clause because one of the following two reasons
1. nesting of WITH clause within WITH clause not supported yet
2. For a set query, WITH clause can't be specified for a branch.
3. WITH clause can't sepecified within parentheses.
*Action: correct query and retry
Encapsulate your WITH statement in a dummy select.
select column1 from TABLE_A
union
select * from (
with abcd as (select * from TABLE_B)
select column2 from TABLE_A A, abcd
where abcd.m_reference = A.m_reference
)
Just define the CTE first, before the actual UNION query. Then use it as you would a regular table:
with abcd as (select * from TABLE_B)
select column1 from TABLE_A
union
select column2
from TABLE_A A
inner join abcd
on abcd.m_reference = A.m_reference
You can use multiple CTE as follows:
with cte1 AS (...),
cte2 AS (...)
select * from ...
Encapsulating it is the way to go if you have multiple WITHs; for example I just had to do this monstrosity to quickly pull in data from ID numbers from an Excel sheet
select * from (
with childvendor as (
select vendornumber, name From vendor where vendornumber = '0000800727'
)
select
v.vendornumber as parentvendor,
v.name as parentname,
cv.vendornumber as childvendor,
cv.name as childname
From
vendor v, childvendor cv
where
v.vendornumber = '0000800004'
)
UNION ALL
select * from (
with childvendor as (
select vendornumber, name From vendor where vendornumber = '0000800042'
)
select
v.vendornumber as parentvendor,
v.name as parentname,
cv.vendornumber as childvendor,
cv.name as childname
From
vendor v, childvendor cv
where
v.vendornumber = '0000800035'
)
And so on

Oracle: Create a View with Auto Increment id column

I have created a view that fills data from different tables. I used 10 select statements and combine the results of those select statements using UNION ALL.
I want to add primary key column to my view. because I have to create XML file using data in this view. so I need a primary key column for some process in my XML building application.
I have add rownum to all my select statements. But it returned duplicate ids. because rownum in each select statements start from 1.
Then I have created a sequence and tried use nextval . But I can't use sequence because my select statements has group by and order by.
Is there any way to do that ?
You can do a select over the union, for example:
SELECT rownum(),*
FROM (SELECT * FROM tableA UNION ALL SELECT * FROM tableB)
UPDATED
SELECT rownum, t.*
FROM (SELECT * FROM tableA UNION ALL SELECT * FROM tableB) t

Resources