Combining sets+tables+windowfunction in one go - oracle

I want to make something like this work in proc sql:
proc sql;
%connect_to_sql_macro;
create table sql.table as
(
select some_id, date from connection to oracle
(
select some_id, date, row_number()over(partition by some_id order by date) as row from dataset d join sql_table s on d.some_id=s.some_id
) where row=1
Basically i need to create table in oracle based on dataset joined with oracle table and take the first date for each id.
If i use "from oracle" pass through it doesn't see the dataset, if i make it the other way around i can't use window functions(row_number()) becouse they are not in SAS. For now i create a table from that dataset and then do a pass through but it's large and i need to do it in one go. Any suggestions?

You're probably better off doing it in SAS.
Can be done in one step too
libname lib <oracle connection options>;
proc sql;
select some_id
,date
from dataset d
inner join lib.sql_table s
on d.some_id=s.some_id
group by some_id
having date=min(date)
;
quit;
or
proc sql;
%connect_to_sql_macro;
select some_id
,date
from dataset d
inner join (select * from connection to oracle (
select * from sql_table
)
) s
on d.some_id=s.some_id
group by some_id
having date=min(date)
;
quit;
Also, limit as much as you can the amount of records that are being read from the oracle table.

Related

How to write SQL query for extracting 50 percent of records from a table?

How to retrieve 50% of records in ANSI SQL. In MS SQL Server we have Top with percent. But I want to get in Oracle and PostgreSQL.
In Postgres, one option uses percent_rank(). Assuming that id is your ordering column:
select *
from (select t.*, percent_rank() over(order by id) prn from mytable t) t
where prn <= 0.5
This would also work in Oracle, but for that database I would prefer a fetch clause:
select *
from mytable t
order by id
fetch first 50 percent rows only

How to copy all constrains and data form one schema to another in oracle

I am using Toad for oracle 12c. I need to copy a table and data (40M) from one shcema to another (prod to test). However there is an unique key(not the PK for this table) called record_Id col which has something data like this 3.000*******19E15. About 2M rows has same numbers(I believe its because very large number) which are unique in prod. When I try to copy it violets the unique key of that col. I am using toad "export data to another schema" function to copy the data.
when I execute query in prod
select count(*) from table_name
OR
select count(distinct(record_id) from table_name
Both query gives the exact same numbers of data.
I don't have DBA permission. How do I copy all data without violating unique key of the table.
Thanks in advance!
You can use UPSERT for decisional INSERT or UPDATE or you may write small procedure for this.
you may consider to use NOT EXISTS, but your data is big and it might not be resource efficient.
insert into prod_tab
select * from other_tab t1 where NOT exists (
select 1 from prod_tab t2 where t1.id = t2.id
);
In Oracle you can use a MERGE query for that.
The following query proceeds as follows for each data row :
if the source record_id does not yet exist in the target table, a new record is inserted
else, the existing record is updated with source values
For the sake of the example, I assumed that there are two other columns in the table : column1 and column2.
MERGE INTO target_table t1
USING (SELECT * from source_table t2)
ON (t1.record_id = t2.record_id)
WHEN MATCHED THEN UPDATE SET
t1.column1 = t2.column1,
t1.column2 = t2.column2
WHEN NOT MATCHED THEN INSERT
(record_id, column1, column2) VALUES (t2.record_id, t2.column1, t2.column2)

PLSQL ORACLE : Inner join between table variables

I need to create two table-type variables in oracle and make inner join between them.
I can't create temporary table in the source database because I dont have privileges.
How to create an anonymous plsql block in oracle something relative to this code in SQL server?
DECLARE #TB_PROJETO TABLE
(
ID INT,
NAME NVARCHAR(MAX)
)
DECLARE #TB_CAMERA TABLE
(
ID INT,
NAME NVARCHAR(MAX),
PROJETOID INT
)
BEGIN
INSERT INTO #TB_PROJETO
SELECT [ProjetoId], [Nome] FROM [dbo].[TbProjeto]
INSERT INTO #TB_CAMERA
SELECT [CameraId], [Nome],[ProjetoId] FROM [dbo].[TbCamera]
SELECT * FROM #TB_PROJETO P INNER JOIN #TB_CAMERA C ON P.ID = C.PROJETOID
END
The use of table variables is very common in SQL Server but Oracle doesn't have them because Oracle is pretty good at efficiently joining tables. So in Oracle the equivalent of your T-SQL routine would just be this:
SELECT c.ProjetoId
, p.Nome as project_nome
, c.CameraId
, c.Nome as camera_nome
FROM TbProjeto p
inner join TbCamera c
ON P.ID = C.PROJETOID
Column aliasing optional but done for clarity

global temporary table hibernate

I'm trying to replace a giant IN clause (hundreds of values) with a JOIN for performance reasons, so I created a global temp table (Oracle) hoping that may be a viable alternative:
CREATE GLOBAL TEMPORARY TABLE TMP_USER_GUID (
user_guid varchar(20)
)
ON COMMIT DELETE ROWS
When I run my sql manually, it works fine:
INSERT ALL
INTO ent.tmp_usr_guid VALUES ('00JD49W7IJ93ZU5MBWBQ')
-- as many INTO statements as I would have IN parameters
SELECT * FROM DUAL;
SELECT u.guid, u.first_name, u.last_name, ...
FROM usr u
JOIN ...
JOIN ...
JOIN tmp_usr_guid tug ON u.guid = tug.usr_guid
When I try running it as a native sql statement using Hibernate (5.2.12.FINAL) it throws:
org.hibernate.QueryException: unexpected char: ';' [INSERT ALL INTO
ent.tmp_usr_guid VALUES ('00JD49W7IJ93ZU5MBWBQ') SELECT * FROM DUAL;
SELECT u.guid,
Any thoughts on the correct approach to take?

Want to create Stored Procedure of new table with calculated variable

I want to create a stored procedure using the table from Oracle and want to access in SAS EG.
I have below code .
create table xyz as
select * from (
select a,b,c,d
from table_name
)
pivot (MIN('X') for Variable_name in (
'PQR' as PQR, 'PGT' as PGT, 'KLD' as KLD,
'opd' as opd
)
)
order by Variable_name;
Is it possible to make this table as stored procedure? And if not then please suggest solution.
If I'm understanding your problem correctly you should be able to do this using SQL pass-through. You will just need to specify the Oracle database in the libname statement in SAS which will look something like this:
libname mydblib oracle user=user_name password=pw path='myoracleserver';
You can then access this using proc sql in SAS.
proc sql;
connect using mydblib;
create table xyz as
select * from connection to mydblib (
select * from (
select a,b,c,d
from table_name
)
pivot (MIN('X') for Variable_name in (
'PQR' as PQR, 'PGT' as PGT, 'KLD' as KLD,
'opd' as opd
)
)
order by Variable_name
);
quit;
This code creates the table xyz in your SAS work library.

Resources