I have this query below that works in Oracle, however, needed to run in SAS proc sql to join with other data. Does anyone know how to convert this statement to work with proc sql? Also, if someone is familiar with this output, how come with the invoice date range set between April and May 2021, this query still pulls in ALL dates in the ouput?
with pay_cte( vendor_id,invoice_id, pay_amt,pay_cnt ) as (
select vendor_id,invoice_id, pay_amt,count(*)
from ps_voucher
where invoice_dt between '01-Apr-2021' and '31-May-2021'
group by vendor_id,invoice_id, pay_amt
having count(*)>1)
select t.vendor_id, t.voucher_id,t.INVOICE_ID,t.gross_amt, t.INVOICE_DT
from ps_voucher t
join pay_cte p on t.vendor_id=p.vendor_id and t.invoice_id = p.invoice_id
and t.gross_amt=p.pay_amt
I don't speak Oracle.
What does this do?
with pay_cte( vendor_id,invoice_id, pay_amt,pay_cnt ) as
the WITH statement in Oracle is looking for a similar match of (vendor_id, invoice_id, gross_amt) having more than 1 match for potential duplicates
The logic is trying to identify potential match in the data for a set of criteria (vendor_id, invoice_id, gross_amt) ... another would be for (invoice_id, invoice_dt, gross_amt) for example
Where is the "other data" coming from? If it is SAS data and your Oracle data is large, it would be more efficient to load your SAS data as an Oracle temporary table and continue to do all of your processing in Oracle.
1.SAS does not support the Oracle WITH Clause.
2.If the code you have given is exactly the code you want to run, then the join is not needed. You are pulling the data from ps_voucher in both the WITH clause subquery and join. In fact the way the join is structured it pulls all the data fro ps_voucher. In order to get data for invoice date range set between April and May 2021, the following query should suffice. Do make changes as needed. I don't have your data to test it.
proc sql;
create table pay_cte (drop=cnt) as
select vendor_id, voucher_id, INVOICE_ID, gross_amt, INVOICE_DT, count(*) as cnt
from ps_voucher
where invoice_dt between '01-Apr-2021' and '31-May-2021'
group by vendor_id,invoice_id, pay_amt
having count(*)>1 ;
quit;
Something like this? Note that you should use the numeric value for the dates to get an accurate selection.
proc sql;
select t.vendor_id
, t.voucher_id
, t.INVOICE_ID
, t.gross_amt
, t.INVOICE_DT
from ps_voucher t join
(select vendor_id,invoice_id, pay_amt, count(*) as pay_cnt
from ps_voucher
where invoice_dt between '01APR2021'd and '31MAY2021'd
group by vendor_id, invoice_id, pay_amt
having count(*)>1) p
on t.vendor_id = p.vendor_id
and t.invoice_id = p.invoice_id
and t.gross_amt=p.pay_amt
;
quit;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.