Related
How do I do the below using JOIN:
Select
id_pk, col1, col2,col
From table1 A
Where NOT EXISTS
(select 1 from table2 B
Where A.id_pk = B.id_pk
and A.col1 = B.col1
and A.col2 = B.col2
);
Here, join query cannot be simply used, as we know that both tables share their primary key id_pk, we could rather obtain the primary keys of those records which satisfy the conditions A.id_pk = B.id_pk (Equi-join), A.col1 = B.col1 and A.col2 = B.col2. And we can use this set of primary keys to obtain those records whose primary keys do not match using NOT IN operator. The join query is given as a sub-query, in this case.
Query:
SELECT
id_pk, col1, col2, col
FROM table1
WHERE id_pk NOT IN (
SELECT A.id_pk
FROM table1 A, table2 B
WHERE A.id_pk = B.id_pk
AND A.col1 = B.col1
AND A.col2 = B.col2
);
i have table with column name policy_refer, client name and issue_date
policy_refer Client_Name issue_date(entry_date)
0001 Ajaz 01-Jan-2019
0001 Ajaz 05-Jan-2019
0001 Anita 10-Jan-2019
i want to select last update/insert client_name where policy_refer = 0001 , in my select/join query ....
select policy_master.CLIENT_NAME
,POLICY_INSURER_DETAIL.INSURER_NAME
,POLICY_INSURER_DETAIL.INSURER_BRANCH
,POLICY_INSURER_DETAIL.policy_number
,policy_master.policy_refer
,policy_master.POLICY_CLASS
,policy_master.POLICY_PRODUCT
,policy_master.P_ISSUE_DATE
,policy_master.EXPIRY_DATE
,sum(policy_master.TOTAL_SUMINSURED)
,sum(policy_master.GROSS)
,sum(policy_master.PERMIUM)
from POLICY_MASTER,POLICY_INSURER_DETAIL
where policy_master.policy_refer = POLICY_INSURER_DETAIL.POLICY_REFER
and POLICY_MASTER.POL_ID = POLICY_INSURER_DETAIL.POL_ID
and POLICY_MASTER.EXPIRY_DATE ='19-AUG-20'
and POLICY_MASTER.DOC_STATUS ='Posted'
group by POLICY_MASTER.policy_refer
,POLICY_INSURER_DETAIL.INSURER_NAME
,POLICY_INSURER_DETAIL.INSURER_BRANCH
,POLICY_INSURER_DETAIL.policy_number
,policy_master.policy_refer
,policy_master.EXPIRY_DATE
,policy_master.CLIENT_NAME
,policy_master.POLICY_CLASS
,policy_master.POLICY_PRODUCT
,policy_master.P_ISSUE_DATE;
One option is to find which one's the first (using analytic functions), and then fetch that row. For example:
select column_list_goes_here
from (
--> this is your current query, with the ROW_NUMBER addition
select all your columns here,
--
row_number() over (partition by policy_refer order by issue_date desc) rn
--
from your_tables
where ...
group by ...
--> end of your current query
)
where rn = 1
It appears the table you are talking about is the POLICY_MASTER table and you want the latest row (by ISSUE_DATE) for each policy.
Then you want to filter something like this:
select pm.CLIENT_NAME
,POLICY_INSURER_DETAIL.INSURER_NAME
,POLICY_INSURER_DETAIL.INSURER_BRANCH
,POLICY_INSURER_DETAIL.policy_number
,pm.policy_refer
,pm.POLICY_CLASS
,pm.POLICY_PRODUCT
,pm.P_ISSUE_DATE
,pm.EXPIRY_DATE
,sum(pm.TOTAL_SUMINSURED)
,sum(pm.GROSS)
,sum(pm.PERMIUM)
from (
SELECT *
FROM (
SELECT POL_ID,
CLIENT_NAME,
policy_refer,
POLICY_CLASS,
POLICY_PRODUCT,
P_ISSUE_DATE,
EXPIRY_DATE,
TOTAL_SUMINSURED,
GROSS,
PERMIUM,
ROW_NUMBER() OVER ( PARTITION BY policy_refer /*, pol_id */
ORDER BY ISSUE_DATE DESC ) AS rn
FROM POLICY_MASTER
WHERE EXPIRY_DATE = DATE '2020-08-19'
AND DOC_STATUS ='Posted'
)
WHERE rn = 1
) pm
INNER JOIN POLICY_INSURER_DETAIL pid
ON ( pm.policy_refer = pid.POLICY_REFER
AND pm.POL_ID = pid.POL_ID )
GROUP BY pm.policy_refer
,pid.INSURER_NAME
,pid.INSURER_BRANCH
,pid.policy_number
,pm.policy_refer
,pm.EXPIRY_DATE
,pm.CLIENT_NAME
,pm.POLICY_CLASS
,pm.POLICY_PRODUCT
,pm.P_ISSUE_DATE;
I guess you need the first row after sorting them in descending from issue date -
select policy_master.CLIENT_NAME
,POLICY_INSURER_DETAIL.INSURER_NAME
,POLICY_INSURER_DETAIL.INSURER_BRANCH
,POLICY_INSURER_DETAIL.policy_number
,policy_master.policy_refer
,policy_master.POLICY_CLASS
,policy_master.POLICY_PRODUCT
,policy_master.P_ISSUE_DATE
,policy_master.EXPIRY_DATE
,sum(policy_master.TOTAL_SUMINSURED)
,sum(policy_master.GROSS)
,sum(policy_master.PERMIUM)
from POLICY_MASTER,POLICY_INSURER_DETAIL
where policy_master.policy_refer = POLICY_INSURER_DETAIL.POLICY_REFER
and POLICY_MASTER.POL_ID = POLICY_INSURER_DETAIL.POL_ID
and POLICY_MASTER.EXPIRY_DATE ='19-AUG-20'
and POLICY_MASTER.DOC_STATUS ='Posted'
and rownum = 1
group by POLICY_MASTER.policy_refer
,POLICY_INSURER_DETAIL.INSURER_NAME
,POLICY_INSURER_DETAIL.INSURER_BRANCH
,POLICY_INSURER_DETAIL.policy_number
,policy_master.policy_refer
,policy_master.EXPIRY_DATE
,policy_master.CLIENT_NAME
,policy_master.POLICY_CLASS
,policy_master.POLICY_PRODUCT
,policy_master.P_ISSUE_DATE
ORDER BY P_ISSUE_DATE DESC;
I am working on the following Oracle (PL/SQL) stored procedure:
Procedure myProc(idParam IN Number, RESULT OUT SYS_REFCURSOR)
IS
BEGIN
FOR myMetaData in (select status, idData from Table1 where id=idParam)
LOOP
IF myMetaData.status='test1'
SELECT column1, column2, column3 from Table2 where cond1=cond2;
ELSE
SELECT column1, column2, column3 from Table2 where column4=
(select column4 from.....);
END IF;
END LOOP;
END myProc;
Assuming above is my code now I need to return combined results from both IF clause select statement and Else clause. I tried with dbms_sql.return_result(); but it didn't help.
How can I combine both result sets and return the value?
There are many ways to achieve your requirement however i would prefer to use a table to achieve your requirement. See below:
--Create a table to hold your result of if clause
Create table Rslt (col1 number,col2 number, col3 number);
/
--Use sysrefcursor to get the final result out of the table
Procedure myProc(idParam IN Number, RESULT OUT SYS_REFCURSOR)
IS
BEGIN
FOR myMetaData in (select status, idData from Table1 where id=idParam)
LOOP
IF myMetaData.status='test1'
insert into rslt SELECT column1, column2, column3 from Table2 where cond1=cond2;
ELSE
insert into rslt SELECT column1, column2, column3 from Table2 where column4=
(select column4 from.....);
END IF;
END LOOP;
Open result for select * from rslt;
END myProc;
Another apporach could be Object Oriented using a Object having table columns. See below:
Create type rslt is object
(col1 number,
col2 number,
col3 number
);
Create type var_rslt is table of rslt ;
Procedure myProc(idParam IN Number, V_RESULT OUT SYS_REFCURSOR)
IS
v_rslt1 var_rslt:=var_rslt();
v_rslt2 var_rslt:=var_rslt();
v_rslt3 var_rslt:=var_rslt();
v_rslt4 var_rslt:=var_rslt();
BEGIN
FOR myMetaData in (select status, idData from Table1 where id=idParam)
LOOP
IF myMetaData.status='test1'
SELECT rslt(column1, column2, column3) bulk collect into v_rslt1 from Table2 where cond1=cond2;
v_rslt2:=v_rslt2 Multiset union all v_rslt1;
ELSE
SELECT rslt(column1, column2, column3) bulk collect into v_rslt13 from Table2 where column4= (select column4 from.....);
v_rslt4:=v_rslt4 multiset union all v_rslt13;
END IF;
END LOOP;
v_rslt2 := v_rslt2 multiset union all v_rslt4;
OPEN V_RESULT FOR SELECT * FROM table( v_rslt2 );
END myProc;
Demo:
Table Preparation:
Create table Table1 (id number, status varchar2(10));
/
Insert into table1 values(1,'test1');
Insert into table1 values(2,'test2');
Create table Table2 (id number,column1 number, column2 number, column3 number);
/
insert into table2 values(1,10,20,30);
insert into table2 values(1,70,60,50);
insert into table2 values(1,20,40,30);
insert into table2 values(2,80,40,20);
insert into table2 values(2,60,20,10);
Create type rslt is object
(col1 number,
col2 number,
col3 number
);
Create type var_rslt is table of rslt ;
Procedure:
CREATE OR REPLACE Procedure myProc(idParam IN Number, V_RESULT OUT sys_refcursor)
IS
v_rslt1 var_rslt:=var_rslt();
v_rslt2 var_rslt:=var_rslt();
v_rslt3 var_rslt:=var_rslt();
v_rslt4 var_rslt:=var_rslt();
BEGIN
FOR myMetaData in (select status, id from Table1)
LOOP
IF myMetaData.status='test1' then
SELECT rslt(column1, column2, column3) bulk collect into v_rslt1 from Table2 where id=myMetaData.id;
v_rslt2:=v_rslt2 Multiset union all v_rslt1;
ELSE
SELECT rslt(column1, column2, column3) bulk collect into v_rslt3 from Table2 where id=myMetaData.id;
v_rslt4:=v_rslt4 multiset union all v_rslt3;
END IF;
END LOOP;
v_rslt4 := v_rslt4 multiset union all v_rslt2;
open V_RESULT for Select * from table(v_rslt4);
END myProc;
Execution:
DECLARE
var sys_refcursor;
var1 NUMBER;
var2 NUMBER;
var3 NUMBER;
BEGIN
myProc(1, var);
LOOP
FETCH var INTO var1,var2,var3;
EXIT WHEN var%notfound;
dbms_output.put_line(var1);
END LOOP;
END;
OUTPUT:
SQL> /
anonymous block completed
80
60
10
70
20
Note: This solution will work on Oracle 11g and onward versions. Incase you are working on lower version of Oracle, then you need to modify the Object definition as below:
Create type rslt is object
(col1 number,
col2 number,
col3 number,
map member function mem return number);
This is due to a bug in Oracle 10g while using MULTISET operator.
Read more about the bug at http://raajeshwaran.blogspot.com/2010/07/pls-00801-internal-error-assert-at-file.html
I have model Activity, and i am storing timeInterval/NSDate when user does some activity, there could be situation when user will take a break for 15 minutes, and will back. I would like to sum time between activities only if difference is less than 10 minutes between them and measure real time of his work. How can i create NSPredicate to achieve that?
Nailed it for you. What I believe is a good example below.
-- Set Employee ID And Date Required Here
DECLARE #ID INT = 7;
DECLARE #Date SMALLDATETIME = '20150615';
--create our table
DECLARE #TableRows TABLE
(
ID TINYINT,
ActionLog SMALLDATETIME
);
-- Insert some data
INSERT INTO #TableRows
VALUES
(10,'20150615 16:01:00'),
(7,'20150615 16:02:00'),
(7,'20150615 16:04:00'),
(10,'20150615 16:04:00'),
(10,'20150615 16:23:00'),
(10,'20150615 16:25:00'),
(10,'20150615 16:26:00');
-- First CTE for Row Numbers
WITH RowNumCTE
AS
(SELECT
ROW_NUMBER() OVER(ORDER BY ActionLog) AS RowNum
, ActionLog
FROM
#TableRows
WHERE
ID = #ID AND
datediff(day, #Date, ActionLog) = 0
)
-- SUM of all the Minutes
SELECT
SUM(DATEDIFF(MINUTE,t2.ActionLog,t1.ActionLog)) as Mins
FROM RowNumCTE t1
LEFT JOIN RowNumCTE t2 ON T1.RowNum = T2.RowNum + 1
WHERE
DATEDIFF(MINUTE,t2.ActionLog,t1.ActionLog) < 10
A better, faster example. This uses LEAD window function (Created in SQL 2012).
-- Set Required Date Here
DECLARE #Date SMALLDATETIME = '20150615';
--create our table
DECLARE #TableRows TABLE
(
TableID INT IDENTITY(1,1) PRIMARY KEY,
ID TINYINT,
ActionLog SMALLDATETIME
);
-- Insert some data
INSERT INTO #TableRows
VALUES
(10,'20150615 16:01:00'),
(7,'20150615 16:02:00'),
(7,'20150615 16:04:00'),
(10,'20150615 16:04:00'),
(10,'20150615 16:23:00'),
(10,'20150615 16:25:00'),
(10,'20150615 16:26:00');
-- First CTE for Row Numbers (To force the LEAD first in the QEP)
WITH AllMinsCTE
AS
(SELECT
ID AS EmployeeID,
DATEDIFF(MINUTE, ActionLog, LEAD(ActionLog) OVER(PARTITION BY id ORDER BY id, actionlog)) as Mins
FROM
#TableRows
WHERE
datediff(day, #Date, ActionLog) = 0
)
SELECT
EmployeeID,
SUM(AllMinsCTE.Mins) as Mins FROM AllMinsCTE
WHERE
AllMinsCTE.Mins < 10
Group BY EmployeeID;
I am trying to get this stored procedure to work. I have been working for a month straight, was up till 3 last night, and am approaching burnout. I really want to get this to work as we have an ad campaign that we spent hundreds on sending traffic to.
USE [redhotkitties2005db]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[proc_rhkprod_lock_items_for_paypal]
#cfuseridid bigint
,#transaction_guid uniqueidentifier = NULL
AS
BEGIN
SET NOCOUNT ON;
declare #tblcartID bigint
,#cfuserid bigint
,#tblproductsid bigint
,#quantity bigint
,#localInventoryID varchar(100)
,#taxologykey bigint
,#name varchar(1000)
,#shortDescription varchar(8000)
,#productDescription varchar(8000)
,#UorLorUL varchar(2)
,#unitPrice money
,#shippingWeight numeric(6, 2)
,#overSize tinyint
,#smallPic1 nvarchar(100)
,#largePic1 nvarchar(100)
,#smallPic2 nvarchar(100)
,#largePic2 nvarchar(100)
,#smallPic3 nvarchar(100)
,#largePic3 nvarchar(100)
SET #transaction_guid = coalesce(#transaction_guid,newid())
declare c1 cursor forward_only for
select rhkProd_tblCart.tablePK AS tblcartID
,rhkProd_tblProducts.productID as tblproductsid
,rhkProd_tblCart.quantity
,rhkProd_tblProducts.localInventoryID
,rhkProd_tblProducts.name
,rhkProd_tblProducts.taxologyKey
,rhkProd_tblProducts.shortDescription
,rhkProd_tblProducts.productDescription
,rhkProd_tblProducts.UorLorUL
,rhkProd_tblProducts.unitPrice
,rhkProd_tblProducts.shippingWeight
,rhkProd_tblProducts.overSize
,rhkProd_tblProducts.smallPic1
,rhkProd_tblProducts.largePic1
,rhkProd_tblProducts.smallPic2
,rhkProd_tblProducts.largePic2
,rhkProd_tblProducts.smallPic3
,rhkProd_tblProducts.largePic3
from rhkProd_tblCart
INNER JOIN rhkProd_tblProducts
on rhkProd_tblCart.tblProductsFK = rhkProd_tblProducts.productID
where rhkProd_tblCart = #cfuserid
open c1
fetch next
from c1
into #tblcartID
,#cfuserid
,#tblproductsid
,#quantity
,#localinventoryID
,#name
,#taxologykey
,#shortdescription
,#productdescription
,#UorLorUL
,#unitprice
,#shippingweight
,#oversize
,#smallpic1
,#largepic1
,#smallpic2
,#largepic2
,#smallpic3
,#largepic3
begin
while ##fetch_status = 0
insert into rhkprod_tblpaypallock (
,[cfuserid]
,[transaction_guid]
,[timestamp]
,[tblproductsFK]
,[quantity]
,[localInventoryID]
,[name]
,[taxologykey]
,[shortdescription]
,[productdescription]
,[uorlorul]
,[unitprice]
,[shippingweight]
,[oversize]
,[smallpic1]
,[largepic1]
,[smallpic2]
,[largepic2]
,[smallpic3]
,[largepic3]
)
values (
,#cfuserid
,#transaction_guid
,getdate()
,#tblproductsid
,#quantity
,#localinventoryID
,#name
,#taxologykey
,#shortdescription
,#productdescription
,#UorLorUL
,#unitprice
,#shippingweight
,#oversize
,#smallpic1
,#largepic1
,#smallpic2
,#largepic2
,#smallpic3
,#largepic3
)
update rhkprod_tblproducts
set quantity = quantity - #quantity
where productid = #tblproductsid
and UorLorUL in ('U','L')
fetch next
from c1
into #tblcartID
,#cfuserid
,#tblproductsid
,#quantity
,#localinventoryID
,#name
,#taxologykey
,#shortdescription
,#productdescription
,#UorLorUL
,#unitprice
,#shippingweight
,#oversize
,#smallpic1
,#largepic1
,#smallpic2
,#largepic2
,#smallpic3
,#largepic3
close c1
deallocate c1
end
END
Your INSERT statement has a stray comma at the start:
insert into rhkprod_tblpaypallock (
,[cfuserid]
Should be
insert into rhkprod_tblpaypallock (
[cfuserid]
Your VALUES clause also has a stray comma:
values (
,#cfuserid
Should be
values (
#cfuserid