Rewriting Correlated Subquery with "not in" clause - sql

For obvious performance reasons, I would like to rewrite an existing Oracle SQL query that includes correlated subqueries involving "not in" clauses. Can this be accomplished through outer joins or perhaps some other technique?
Here is the code:
SELECT TRIM(et.event_id), TRIM(et.cancel_evt_id)
FROM external_transactions et
JOIN transaction_type tt
ON et.transaction_type_id = tt.transaction_type_id
WHERE et.acct = 'ABCDEF'
AND tt.transaction_type_class != 'XYZXYZ'
AND
(
TRIM(et.event_id) NOT IN
(
SELECT TRIM(t1.transaction_evt_id)
FROM transactions t1
WHERE t1.acct = et.acct
AND t1.asset_id = et.asset_id
AND t1.cancel_flag = 'N'
)
OR TRIM(et.cancel_evt_id) NOT IN
(
SELECT TRIM(t2.cancel_evt_id)
FROM transactions t2
WHERE t2.acct = et.acct
AND t2.asset_id = et.asset_id
AND t2.cancel_flag = 'Y'
)
)
;

Aside from comment, this is assuming your "ID" columns are integer based and not string, don't try to convert them.
Also, to help optimize the query, I would ensure you have indexes
External_Transactions ( acct, event_id, cancel_evt_id )
Transaction_Type ( transaction_type_id, transaction_type_class )
Transactions ( transaction_evt_id, acct, asset_id, cancel_flag )
Transactions ( cancel_evt_id, acct, asset_id, cancel_flag )
SELECT
et.event_id,
et.cancel_evt_id
FROM
external_transactions et
JOIN transaction_type tt
ON et.transaction_type_id = tt.transaction_type_id
AND tt.transaction_type_class != 'XYZXYZ'
LEFT OUTER JOIN transactions t1
ON et.event_id = t1.transaction_evt_id
AND et.acct = t1.acct
AND et.asset_id = t1.asset_id
AND t1.cancel_flag = 'N'
LEFT OUTER JOIN transactions t2
ON et.cancel_evt_id = t2.cancel_evt_id
AND et.acct = t2.acct
AND et.asset_id = t2.asset_id
AND t2.cancel_flag = 'Y'
WHERE
et.acct = 'ABCDEF'
AND ( t1.transaction_evt_id IS NULL
OR t2.cancel_evt_id IS NULL )
You might even benefit slightly if the transaction table had an index on
Transactions ( acct, asset_id, cancel_flag, transaction_evt_id, cancel_evt_id )
and the left-join was like
SELECT
et.event_id,
et.cancel_evt_id
FROM
external_transactions et
JOIN transaction_type tt
ON et.transaction_type_id = tt.transaction_type_id
AND tt.transaction_type_class != 'XYZXYZ'
LEFT OUTER JOIN transactions t1
ON et.acct = t1.acct
AND et.asset_id = t1.asset_id
AND (
( t1.cancel_flag = 'N'
AND et.event_id = t1.transaction_evt_id )
OR
( t1.cancel_flag = 'Y'
AND et.cancel_event_id = t1.cancel_evt_id )
)
WHERE
et.acct = 'ABCDEF'
AND t1.transaction_evt_id IS NULL
In both cases, the indexes would be COVERING indexes so it did not have to go back to the raw data pages to confirm other elements of the records

Using NOT EXISTS:
SELECT TRIM(et.event_id), TRIM(et.cancel_evt_id)
FROM external_transactions et
JOIN transaction_type tt
ON et.transaction_type_id = tt.transaction_type_id
WHERE et.acct = 'ABCDEF'
AND tt.transaction_type_class != 'XYZXYZ'
AND NOT EXISTS
(
SELECT 1
FROM transactions t1
WHERE t1.acct = et.acct
AND t1.asset_id = et.asset_id
AND ( ( t1.cancel_flag = 'N'
AND TRIM(et.event_id) = TRIM(t1.transaction_evt_id) )
OR
( t1.cancel_flag = 'Y'
AND TRIM(et.cancel_evt_id) = TRIM(t1.cancel_evt_id) )
)
);

Related

Slow running query of view

I have a view that summarizes calendar specific data, it is constantly showing performance issues and creating help desk tickets from customers.
We had a DBA on staff for a short time but he never showed up to work so was let go. This has largely been a developer managed database. I have run Brent Ozar's Sps (sp_BlitzFirst) and the queries to this view constantly have the highest cost.
Query Plan: https://www.brentozar.com/pastetheplan/?id=ry8Lo6T74
view code
SELECT
rae.ResourceAvailabilityExceptEventId AS MasterEventEntityId,
me.MasterEventId AS MasterEventId,
null AS ParentEventId,
me.MasterEventBillingInfoId AS MasterEventBillingInfoId,
0 AS HasScheduledParentEvent,
me.Subject AS EventSubject,
me.Description AS EventDescription,
me.EventStartDate AS EventStartDate,
me.EventEndDate AS EventEndDate,
me.TimeZone AS TimeZone,
mebi.TotalBillAmount AS BillAmount,
null AS CancelledReason,
null AS HasDiagnosis,
null AS ParticipantAuthorizationId,
null AS AuthorizationNumber,
null AS AuthorizationDescription,
null AS BillingSourceName,
null AS BillingSourceTypeId,
me.EventTypeId AS EventTypeId,
cet.Description AS EventType,
me.EventSubTypeId AS EventSubTypeId,
cest.Description AS EventSubType,
1 AS IsTimeOff,
0 AS IsInsurance,
CASE WHEN me.MasterEventBillingInfoId is null THEN 0 ELSE 1 END AS IsBillable,
0 AS IsScheduled,
0 AS IsCompleted,
0 AS IsRecurring,
0 AS IsLinkedEvent,
null AS ChildEventTypeId,
null AS ChildEventType,
'timeoff' AS EventStatus,
null AS EventStatusId,
null AS WorkflowStatusId,
null AS WorkflowStatusDescription,
ra.LinkId AS LinkId,
ra.EntityId AS EntityId,
IIF(ra.EntityId = 'E32955F7-1CE8-46A1-98D3-06A69FA4B29E',1,0) AS IsAssignedParticipant,
IIF(ra.EntityId = '173F0473-747A-48F6-B7E8-06948370AAF8',1,0) AS IsAssignedEmployee,
par.PersonId AS ParticipantId,
emp.PersonId AS AssignedEmployeeId,
null AS BillUnderEmployeeId,
null AS SupervisorEmployeeId,
par.FirstName AS ParticipantFirstName,
par.LastName AS ParticipantLastName,
emp.FirstName AS AssignedEmployeeFirstName,
emp.LastName AS AssignedEmployeeLastName,
null AS BillUnderEmployeeFirstName,
null AS BillUnderEmployeeLastName,
null AS SupervisorEmployeeFirstName,
null AS SupervisorEmployeeLastName,
null AS CredentialId,
null AS CredentialName,
me.LocationId AS LocationId,
o.Name AS Location,
0 AS PublishedScoreSheetCount,
0 AS SessionCount,
0 AS AuthItemCount,
null AS BillCodes,
pstat.Description AS PayrollStatus,
me.PayrollStatusId AS PayrollStatusId,
me.PayrollLastExportDate AS PayrollLastExportDate,
me.PayCodeId AS PayCodeId,
pc.Name AS PayCodeName
FROM Data.MasterEvent me
JOIN Data.ResourceAvailabilityExceptEvent rae WITH ( NOLOCK ) ON me.MasterEventId = rae.ResourceAvailabilityExceptEventId
JOIN Data.ResourceAvailability ra WITH ( NOLOCK ) ON rae.ResourceAvailabilityId = ra.ResourceAvailabilityId AND ra.IsSoftDeleted = 0
JOIN Mgr.Code cet WITH ( NOLOCK ) on cet.CodeId = me.EventTypeId
LEFT JOIN Mgr.Code cest WITH ( NOLOCK ) on cest.CodeId = me.EventSubTypeId
LEFT JOIN Data.MasterEventBillingInfo mebi WITH ( NOLOCK ) on me.MasterEventBillingInfoId = mebi.MasterEventBillingInfoId
LEFT JOIN Data.Person emp WITH ( NOLOCK ) on ra.LinkId = emp.PersonId AND ra.EntityId = '173F0473-747A-48F6-B7E8-06948370AAF8'
LEFT JOIN Data.Person par WITH ( NOLOCK ) on ra.LinkId = par.PersonId AND ra.EntityId = 'E32955F7-1CE8-46A1-98D3-06A69FA4B29E'
LEFT JOIN Data.Organization o WITH ( NOLOCK ) ON o.OrganizationId = me.LocationId AND o.IsSoftDeleted = 0
LEFT JOIN Mgr.Code pstat WITH ( NOLOCK ) on pstat.CodeId = me.PayrollStatusId
LEFT JOIN Data.PayCode pc WITH(NOLOCK) on pc.PayCodeId = me.PayCodeId
WHERE me.IsSoftDeleted = 0
UNION
SELECT
mee.MasterEventEntityId,
mee.MasterEventId,
me.ParentEventId,
me.MasterEventBillingInfoId,
CASE WHEN separent.ScheduledEventId is null THEN 0 ELSE 1 END as HasScheduledParentEvent,
me.Subject as EventSubject,
me.Description as EventDescription,
me.EventStartDate,
me.EventEndDate,
me.TimeZone,
mebi.TotalBillAmount AS BillAmount,
COALESCE(se.CancelledReason,sece.CancelledReason,null) AS CancelledReason,
IIF(egb.DiagnosisCodes IS NOT NULL,1,0) AS HasDiagnosis,
mebi.ParticipantAuthorizationId,
auth.AuthorizationNumber,
auth.Description as AuthorizationDescription,
billsrccmp.Name as BillingSourceName,
billsrc.BillingSourceTypeId,
me.EventTypeId,
cet.Description as EventType,
me.EventSubTypeId,
cest.Description as EventSubType,
0 AS IsTimeOff,
CASE
WHEN billsrc.BillingSourceTypeId = 'CCBDBCFC-2225-4511-B617-190430D1897C' THEN 1
else 0 END as IsInsurance,
CASE WHEN me.MasterEventBillingInfoId is null THEN 0 ELSE 1 END as IsBillable,
CASE WHEN se.ScheduledEventId is null THEN 0 ELSE 1 END as IsScheduled,
CASE WHEN ce.CompletedEventId is null THEN 0 ELSE 1 END as IsCompleted,
CASE WHEN se.ScheduleRecurrenceId is null THEN 0 ELSE 1 END as IsRecurring,
IIF(meparent.EventTypeId = '7d881908-d373-43eb-a550-ca5e6b55137c', 0, 1) IsLinkedEvent,
pevstat.EventTypeId as ChildEventTypeId,
pevstat.EventType as ChildEventType,
COALESCE(pevstat.EventStatus, evstat.EventStatus) as EventStatus,
ce.EventStatusId,
ce.WorkflowStatusId,
ceC.Description,
mee.LinkId,
mee.EntityId,
IIF(mee.LinkId = par.ParticipantId, 1, 0) as IsAssignedParticipant,
IIF(mee.LinkId = me.AssignedEmployeeId, 1, 0) as IsAssignedEmployee,
par.ParticipantId,
aemp.EmployeeId as AssignedEmployeeId,
buemp.EmployeeId as BillUnderEmployeeId,
semp.EmployeeId as SupervisorEmployeeId,
pperson.FirstName as ParticipantFirstName,
pperson.LastName as ParticipantLastName,
aeperson.FirstName as AssignedEmployeeFirstName,
aeperson.LastName as AssignedEmployeeLastName,
bueperson.FirstName as BillUnderEmployeeFirstName,
bueperson.LastName as BillUnderEmployeeLastName,
seperson.FirstName as SupervisorEmployeeFirstName,
seperson.LastName as SupervisorEmployeeLastName,
c.CredentialId,
c.Name as CredentialName,
me.LocationId,
o.Name AS Location,
COALESCE(sss.ScheduledScoreSheetCount, css.CompletedScoreSheetCount, 0) as PublishedScoreSheetCount,
COALESCE(sss.ScheduledSessionCount, css.CompletedSessionCount, 0) as SessionCount,
aai.ApptAuthItemCount as AuthItemCount,
bc.BillCodes,
pstat.Description as PayrollStatus,
me.PayrollStatusId,
me.PayrollLastExportDate,
pc.PayCodeId,
pc.Name AS PayCodeName
FROM Data.MasterEventEntity mee WITH ( NOLOCK )
JOIN Data.MasterEvent me WITH ( NOLOCK ) on mee.MasterEventId = me.MasterEventId AND me.IsSoftDeleted = 0
JOIN Views.EventStatus evstat on evstat.MasterEventId = me.MasterEventId
LEFT JOIN Data.Organization o WITH ( NOLOCK ) ON o.OrganizationId = me.LocationId AND o.IsSoftDeleted = 0
LEFT JOIN Views.EventGroupingBase egb on egb.MasterEventId = mee.MasterEventId
LEFT JOIN Data.ScheduledEvent se WITH ( NOLOCK ) on se.ScheduledEventId = me.MasterEventId
LEFT JOIN Data.CompletedEvent ce WITH ( NOLOCK ) on ce.CompletedEventId = me.MasterEventId
LEFT JOIN Mgr.Code ceC WITH ( NOLOCK ) on ce.WorkflowStatusId = ceC.CodeId
LEFT JOIN Data.ScheduledEvent sece WITH ( NOLOCK ) on sece.ScheduledEventId = ce.ScheduledEventId
JOIN Mgr.Code cet WITH ( NOLOCK ) on cet.CodeId = me.EventTypeId
LEFT JOIN Mgr.Code cest WITH ( NOLOCK ) on cest.CodeId = me.EventSubTypeId
LEFT JOIN Data.MasterEvent meparent WITH ( NOLOCK ) on meparent.MasterEventId = me.ParentEventId
LEFT JOIN Data.ScheduledEvent separent WITH ( NOLOCK ) on separent.ScheduledEventId = me.ParentEventId
LEFT JOIN Views.ParentEventStatus pevstat on me.EventTypeId = '7d881908-d373-43eb-a550-ca5e6b55137c' AND pevstat.MasterEventId = me.MasterEventId
LEFT JOIN Data.MasterEventBillingInfo mebi WITH ( NOLOCK ) on mebi.MasterEventBillingInfoId = me.MasterEventBillingInfoId and mebi.IsSoftDeleted = 0
LEFT JOIN Mgr.Code pstat WITH ( NOLOCK ) on pstat.CodeId = me.PayrollStatusId
LEFT JOIN Data.PayCode pc WITH(NOLOCK) on pc.PayCodeId=me.PayCodeId
LEFT JOIN Data.Participant par WITH ( NOLOCK ) on par.ParticipantId = COALESCE(mebi.ParticipantId, mee.LinkId)
LEFT JOIN Data.Person pperson WITH ( NOLOCK ) on pperson.PersonId = par.ParticipantId and pperson.IsSoftDeleted = 0
LEFT JOIN Data.Employee buemp WITH ( NOLOCK ) on buemp.EmployeeId = mebi.BillUnderEmployeeId
LEFT JOIN Data.Person bueperson WITH ( NOLOCK ) on bueperson.PersonId = buemp.EmployeeId and bueperson.IsSoftDeleted = 0
LEFT JOIN Data.Employee aemp WITH ( NOLOCK ) on aemp.EmployeeId = me.AssignedEmployeeId
LEFT JOIN Data.Person aeperson WITH ( NOLOCK ) on aeperson.PersonId = aemp.EmployeeId and aeperson.IsSoftDeleted = 0
LEFT JOIN Data.Credential c WITH ( NOLOCK ) on c.CredentialId = mebi.CredentialId and c.IsSoftDeleted = 0
LEFT JOIN Data.Employee semp WITH ( NOLOCK ) on semp.EmployeeId = mebi.SupervisorEmployeeId
LEFT JOIN Data.Person seperson WITH ( NOLOCK ) on seperson.PersonId = semp.EmployeeId and seperson.IsSoftDeleted = 0
LEFT JOIN Data.ParticipantAuthorization auth WITH ( NOLOCK ) on auth.ParticipantAuthorizationId = mebi.ParticipantAuthorizationId and auth.IsSoftDeleted = 0
LEFT JOIN Data.Contract authContract WITH ( NOLOCK ) on authContract.ContractId = auth.ContractId and authContract.IsSoftDeleted = 0
LEFT JOIN Data.BillingSource billsrc WITH ( NOLOCK ) on billsrc.BillingSourceId = authContract.BillingSourceId
LEFT JOIN Data.Company billsrccmp WITH ( NOLOCK ) on billsrccmp.CompanyId = billsrc.BillingSourceId and billsrccmp.IsSoftDeleted = 0
LEFT JOIN Data.InvoiceCharge ic WITH ( NOLOCK ) on ic.CompletedEventId = me.MasterEventId and ic.InvoiceChargeStatusId != 'A2D34290-8630-4735-ACCF-E08D3D1A9480' and ic.IsSoftDeleted = 0
LEFT JOIN Data.Invoice inv WITH ( NOLOCK ) on ic.InvoiceId = inv.InvoiceId and inv.IsSoftDeleted = 0
LEFT JOIN (SELECT
MasterEventBillingInfoId,
count(AuthorizationItemId) ApptAuthItemCount
FROM Data.MasterEventBillingInfoAuthItem mebiai WITH ( NOLOCK )
WHERE mebiai.IsSoftDeleted = 0
GROUP BY mebiai.MasterEventBillingInfoId) aai ON aai.MasterEventBillingInfoId = mebi.MasterEventBillingInfoId
LEFT JOIN (
SELECT
mbi2.MasterEventBillingInfoId,
STUFF((
SELECT ',' + CONCAT(bc.Name,
IIF(caeai.Modifier1 != '', CONCAT('-', caeai.Modifier1), ''),
IIF(caeai.Modifier2 != '', CONCAT(' ', caeai.Modifier2), ''),
IIF(caeai.Modifier3 != '', CONCAT(' ', caeai.Modifier3), ''),
IIF(caeai.Modifier4 != '', CONCAT(' ', caeai.Modifier4), ''))
FROM Data.MasterEventBillingInfoAuthItem caeai WITH ( NOLOCK )
JOIN Data.AuthorizationItem ai WITH ( NOLOCK ) ON caeai.AuthorizationItemId = ai.AuthorizationItemId AND ai.IsSoftDeleted = 0
JOIN Data.FeeScheduleItem fsi WITH ( NOLOCK ) ON ai.FeeScheduleItemId = fsi.FeeScheduleItemId AND fsi.IsSoftDeleted = 0
JOIN Data.BillCode bc WITH ( NOLOCK ) ON bc.BillCodeId = fsi.BillCodeId AND bc.IsSoftDeleted = 0
WHERE mbi2.MasterEventBillingInfoId = caeai.MasterEventBillingInfoId AND caeai.IsSoftDeleted = 0
ORDER BY bc.Name
FOR XML PATH ('')), 1, 1, '') AS BillCodes
FROM Data.MasterEventBillingInfo mbi2 WITH ( NOLOCK )
) bc ON bc.MasterEventBillingInfoId = mebi.MasterEventBillingInfoId
LEFT JOIN (SELECT
s.ScheduledEventId,
count(s.ScoreSheetId) ScheduledScoreSheetCount,
count(SessionId) ScheduledSessionCount
FROM Data.ScheduledEventScoreSheet s WITH ( NOLOCK )
left join Data.DataSheet ds on s.ScoreSheetId = ds.DataSheetId
WHERE s.IsSoftDeleted = 0 AND ds.DefinitionFinishedDate IS NOT NULL AND ds.CompletionDate IS NULL
GROUP BY s.ScheduledEventId) sss ON sss.ScheduledEventId = me.MasterEventId
LEFT JOIN (SELECT
s.CompletedEventId,
count(ScoreSheetId) CompletedScoreSheetCount,
count(SessionId) CompletedSessionCount
FROM Data.CompletedEventScoreSheet s WITH ( NOLOCK )
WHERE s.IsSoftDeleted = 0
GROUP BY s.CompletedEventId) css ON css.CompletedEventId = me.MasterEventId
WHERE mee.ShowOnCalendar = 1 AND mee.IsSoftDeleted = 0
I need some direction on what I can do, even if it is just recommendations on some good reliable DBA consultants I can bring in.
It might be not the only one big problem, but it looks like you have Key Lookup for 7K values in MasterEventBillingInfoAuthItem table and 300 Lookups in MasterEvent table. Review indexing on these tables.

How to Convert an Outer Join Select Query to MERGE in Oracle

How can I convert this simple Outer Join to MERGE to update FT.SS to a certain value for the selected rows:
SELECT FT.SS FROM FT_T FT LEFT OUTER JOIN DC_T DC
ON FT.ID = DC.ID AND FT.CN = DC.CN
WHERE FT.GID = 'AB' AND SS = 'C' AND FT.DEL = 'N' AND PR_S IS NULL AND EN_S IS NULL
AND (DC.ID IS NULL OR DC.SIGNED IS NULL);
It's relatively easy to do it with UPDATE:
UPDATE FT_T FTX
SET FTX.SS = 'X'
WHERE FT.GID = 'AB' AND SS = 'C' AND FT.DEL = 'N'
AND PR_S IS NULL AND EN_S IS NULL
AND (FTX.ID, FTX.CN) = (
SELECT FT.ID, FT.CN FROM FT_T FT LEFT OUTER JOIN DC_T DC
ON FT.ID = DC.ID AND FT.CN = DC.CN
WHERE FT.GID = 'AB' AND SS = 'C' AND FT.DEL = 'N' AND PR_S IS NULL AND EN_S IS NULL
AND (DC.ID IS NULL OR DC.SIGNED IS NULL)
)
But can it be done with MERGE?
Your merge statement would look like:
MERGE INTO ft_t tgt
USING (SELECT ft.id,
ft.cn
FROM ft_t ft
LEFT OUTER JOIN dc_t dc ON ft.id = dc.id AND ft.cn = dc.cn
WHERE ft.gid = 'AB'
AND ft.ss = 'C'
AND ft.del = 'N'
AND ft.pr_s IS NULL
AND ft.en_s IS NULL
AND (dc.id IS NULL OR dc.signed IS NULL)) src
ON (tgt.id = src.id AND tgt.cn = src.cn) -- assuming these two columns are the primary key for the ft_t table
WHEN MATCHED THEN
UPDATE SET tgt.ss = 'X';

How to speedup this query?

Do you have some idea of how to speedup this query:
SELECT Vosol = ( CASE WHEN EXISTS ( SELECT Id
FROM trs.CollectionHeaderView AS chv
WHERE chv.ItemNum = itm.ItemNum
AND chv.CollectionType = '1' )
THEN ISNULL(itm.Amount, 0)
ELSE 0
END ) ,
Vakhast = ( CASE WHEN EXISTS ( SELECT Id
FROM trs.CollectionHeaderView AS chv
WHERE chv.ItemNum = itm.ItemNum
AND chv.CollectionType = '2' )
THEN ISNULL(itm.Amount, 0)
ELSE 0
END )
FROM trs.TrsDocRcvItem AS itm
LEFT JOIN trs.TrsDocRcvHeader AS hdr ON itm.HeaderRef = hdr.Id
LEFT JOIN acc.DL AS dl ON dl.Id = hdr.DLRef
LEFT JOIN trs.TrsDocType AS docType ON docType.Id = hdr.DocTypeRef
INNER JOIN sle.SleCustomer AS customer ON customer.DLRef = dl.Id
LEFT JOIN trs.AccOperation AS operation ON operation.Id = itm.AccOperationRef
WHERE hdr.DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 )
AND ( hdr.State = '1'
OR hdr.State = '2'
)
AND operation.StateType = '1'
I'm trying to optimize sql query which now takes about 6 second to execute.
What more can I do to speedup this query?
I'm using Microsoft Sql Server.
Use OUTER APPLY to remove the two correlated sub-queries.
SELECT Vosol = CASE WHEN chv1 IS NOT NULL THEN Isnull(itm.Amount, 0) ELSE 0 END,
Vakhast = CASE WHEN chv2 IS NOT NULL THEN Isnull(itm.Amount, 0) ELSE 0 END
FROM trs.TrsDocRcvItem AS itm
INNER JOIN trs.TrsDocRcvHeader AS hdr
ON itm.HeaderRef = hdr.Id
--LEFT JOIN acc.DL AS dl
-- ON dl.Id = hdr.DLRef
--LEFT JOIN trs.TrsDocType AS docType
-- ON docType.Id = hdr.DocTypeRef
--INNER JOIN sle.SleCustomer AS customer
-- ON customer.DLRef = dl.Id
INNER JOIN trs.AccOperation AS operation
ON operation.Id = itm.AccOperationRef
OUTER apply (SELECT Max(CASE WHEN chv.CollectionType = '1' THEN id END) AS chv1,
Max(CASE WHEN chv.CollectionType = '2' THEN id END) AS chv2
FROM trs.CollectionHeaderView AS chv
WHERE chv.ItemNum = itm.ItemNum
AND chv.CollectionType IN ( '1', '2' )) oa
WHERE hdr.DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 )
AND hdr.State IN ( '1', '2' )
AND operation.StateType = '1'
I have commented out the acc.DL and sle.SleCustomer tables. I don't see any use of it other than filtering records. If you really need it then uncomment it.
Also I have commented the trs.TrsDocType table which again has no use. Unless it has one to many relationship with trs.TrsDocRcvHeader table. If it has one to many relationship then the result simply get duplicated for no reason since you are not selecting anything from trs.TrsDocType table.
Still if the query is running slow then you need to create Indexes on the tables involved. Also make sure the statistics are up-to-date
After analyzing your execution plan, TrsDocRcvItem table costs 47%. Creating a index on TrsDocRcvItem table should help the query
CREATE NONCLUSTERED INDEX NIX_TrsDocRcvItem
ON [Trs].[TrsDocRcvItem] (AccOperationRef,ItemNum,HeaderRef)
INCLUDE (Amount)
Suggested index from the execution plan you have posted
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [Trs].[TrsDocRcvItem] ([AccOperationRef])
INCLUDE ([ItemNum],[Amount],[HeaderRef])
SELECT Vosol = ( CASE WHEN EXISTS ( SELECT Id
FROM trs.CollectionHeaderView AS chv
WHERE chv.ItemNum = itm.ItemNum
AND chv.CollectionType = '1' )
THEN ISNULL(itm.Amount, 0)
ELSE 0
END ) ,
Vakhast = ( CASE WHEN EXISTS ( SELECT Id
FROM trs.CollectionHeaderView AS chv
WHERE chv.ItemNum = itm.ItemNum
AND chv.CollectionType = '2' )
THEN ISNULL(itm.Amount, 0)
ELSE 0
END )
FROM trs.TrsDocRcvItem AS itm
INNER JOIN
(
SELECT * FROM trs.TrsDocRcvHeader
WHERE DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 )
AND ( State = '1' OR State = '2' )
) hdr ON itm.HeaderRef = hdr.Id
LEFT JOIN acc.DL AS dl ON dl.Id = hdr.DLRef
LEFT JOIN trs.TrsDocType AS docType ON docType.Id = hdr.DocTypeRef
INNER JOIN sle.SleCustomer AS customer ON customer.DLRef = dl.Id
INNER JOIN
( SELECT * FROM trs.AccOperation WHERE StateType = '1'
) operation operation.Id = itm.AccOperationRef
You can replace
WHERE hdr.DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 )
AND ( hdr.State = '1'
OR hdr.State = '2'
)
AND operation.StateType = '1'
To
INNER JOIN
(
SELECT * FROM trs.TrsDocRcvHeader
WHERE DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 )
AND ( State = '1' OR State = '2' )
) hdr ON itm.HeaderRef = hdr.Id
INNER JOIN
( SELECT * FROM trs.AccOperation WHERE StateType = '1'
) operation operation.Id = itm.AccOperationRef
I hope that it will help you.

Oracle complex Join

I have three queries,query 1 and query 2 have to be inner joined on Customer_number
Resultant output from query1 and query2 will be further inner joined on 3 keys customer_number,account_number,bank_number.
Can anyone help me to write the queries for these.I am not able to derive it.
Thanks in advance,
Bhaskar
Query1 :
SELECT
CUST.BANK_NUMBER as CUSTBANKNUMBER,
CUST.CUSTOMER_NUMBER,
CUST.DATE_DECEASE,
FROM
SIGN_LND.T_CUSTOMER_MASTER_FILE_LND CUST
LEFT OUTER JOIN
SIGN_LND.T_CUST_USER_DEF_FIELDS_LND USER_DEF
ON (CUST.CUSTOMER_NUMBER = USER_DEF.CUSTOMER_NUMBER AND CUST.EFF_DT = USER_DEF.EFF_DT)
WHERE
CUST.EFF_DT = TO_DATE('2015-01-22','YYYY-MM-DD')
Query 2 :
SELECT
S.CUSTOMER_NUMBER,
S.ALIAS_ACCOUNT_NBR,
M.BANK_NUMBER,
M.ACCOUNT_NUMBER,
M.PRODUCT_CODE,
M.APPLICATION_NUMBER,
M.APPL_ID
FROM
(
SELECT T1.BANK_NUMBER,
T1.ACCOUNT_NUMBER,
T1.PRODUCT_CODE,
CAST (NULL AS VARCHAR(5)) AS SUB_PRODUCT_CODE,
T1.APPLICATION_NUMBER,
T1.APPL_ID
FROM SIGN_LND.T_LOAN_MASTER_FILE_LND T1
INNER JOIN SIGN_LND.T_LOAN_PRODUCT_DEFINITION_LND T2
ON T1.BANK_NUMBER = T2.BANK_NUMBER
AND T1.PRODUCT_CODE = T2.PRODUCT_CODE
AND T1.EFF_DT=TO_DATE('2015-01-22','YYYY-MM-DD')
AND T2.EFF_DT=TO_DATE('2015-01-22','YYYY-MM-DD')
WHERE T1.PRODUCT_CODE IS NOT NULL
AND T1.DATE_OPEN IS NOT NULL
UNION ALL
SELECT T1.BANK_NUMBER,
T1.ACCOUNT_NUMBER,
T1.PRODUCT_CODE,
T1.PRODUCT_CODE AS SUB_PRODUCT_CODE,
T1.APPLICATION_NUMBER,
T1.APPL_ID
FROM SIGN_LND.T_TA_MASTER_FILE_LND T1
INNER JOIN SIGN_LND.T_TA_PRODUCT_DEFINITION_LND T2
ON T1.BANK_NUMBER = T2.BANK_NUMBER
AND T1.PRODUCT_CODE = T2.PRODUCT_CODE
AND T1.ACCOUNT_TYPE = T2.ACCOUNT_TYPE
AND T1.EFF_DT=TO_DATE('2015-01-22','YYYY-MM-DD')
AND T2.EFF_DT=TO_DATE('2015-01-22','YYYY-MM-DD')
LEFT JOIN SIGN_LND.T_BONUS_INT_MASTER_FILE_LND T3
ON T1.ACCOUNT_NUMBER = T3.ACCOUNT_NUMBER
AND T1.BANK_NUMBER = T3.BANK_NUMBER
AND T3.EFF_DT=TO_DATE('2015-01-22','YYYY-MM-DD')
WHERE T1.PRODUCT_CODE IS NOT NULL
AND T1.ACCOUNT_STATUS_CODE IS NOT NULL
AND T1.DATE_OPEN IS NOT NULL
UNION ALL
SELECT T1.BANK_NUMBER,
T1.ACCOUNT_NUMBER,
T1.PRODUCT_CODE,
T1.PRODUCT_CODE AS SUB_PRODUCT_CODE,
T1.APPLICATION_NUMBER,
T1.APPL_ID,
FROM SIGN_LND.T_TIME_MASTER_FILE_LND T1
INNER JOIN SIGN_LND.T_TM_PRODUCT_DEFINITION_LND T2
ON T1.BANK_NUMBER = T2.BANK_NUMBER
AND T1.PRODUCT_CODE = T2.PRODUCT_CODE
AND T1.EFF_DT=TO_DATE('2015-01-22','YYYY-MM-DD')
AND T2.EFF_DT=TO_DATE('2015-01-22','YYYY-MM-DD')
LEFT JOIN SIGN_LND.T_BONUS_INT_MASTER_FILE_LND T3
ON T1.ACCOUNT_NUMBER = T3.ACCOUNT_NUMBER
AND T1.BANK_NUMBER = T3.BANK_NUMBER
AND T3.EFF_DT=TO_DATE('2015-01-22','YYYY-MM-DD')
WHERE T1.PRODUCT_CODE IS NOT NULL
AND T1.ACCOUNT_STATUS_CODE IS NOT NULL
AND T1.DATE_OPEN IS NOT NULL
)M
INNER JOIN
(
SELECT
T1.ACCOUNT_NUMBER,
T1.CUSTOMER_NUMBER,
T1.RELATIONSHIP ,
T2.ALIAS_ACCOUNT_NBR,
T2.APPLICATION_NUMBER
FROM SIGN_LND.T_CUSTOMER_CROSS_REF_LND T1
INNER JOIN
SIGN_LND.T_ALIAS_ACCT_NBR_CRSS_REF_LND T2
ON T1.ACCOUNT_NUMBER=T2.ACCOUNT_NUMBER
WHERE ALIAS_ACCOUNT_NBR_TYPE='UK'
GROUP BY T1.ACCOUNT_NUMBER,
T1.CUSTOMER_NUMBER,
T1.RELATIONSHIP ,
T2.ALIAS_ACCOUNT_NBR,
T2.APPLICATION_NUMBER
)S
ON M.ACCOUNT_NUMBER=S.ACCOUNT_NUMBER
AND
M.APPLICATION_NUMBER=S.APPLICATION_NUMBER
)
Query3:
SELECT
SPLIT.BANK_NUMBER,
SPLIT.CUSTOMER_NUMBER,
SPLIT.DATE_MOVING_IN,
SPLIT.TITLE,
SPLIT.FIRST_NAME,
SPLIT.SECOND_NAME,
SPLIT.SURNAME,
SPLIT.CURR_APT_NUMBER_UPS,
SPLIT.CURR_HOUSE_NAME_UPS,
SPLIT.CURR_HOUSE_NBR,
SPLIT.CURR_STREET_UPS,
SPLIT.CURR_DISTRICT_UPS,
SPLIT.CURR_POST_TOWN_UPS,
SPLIT.POSTAL_CODE,
SPLIT.CURR_COUNTRY,
CUST_EXT.LOYALTY_CARD_NBR,
XREF.ACCOUNT_NUMBER,
XREF.RELATIONSHIP as RELATIONSHIP_RB,
RB_ALIAS_XREF.APPL_ID as RBXREFAPPID,RB_ALIAS_XREF.ALIAS_ACCOUNT_NBR AS ALIAS_ACCOUNT_NBR_RB,
PROD_OFFER.DATE_CLOSE
FROM
(
SIGN_LND.T_CIF_SPLIT_NAME_ADDR_UPS_LND SPLIT
LEFT OUTER JOIN
SIGN_LND.T_CUST_MASTER_EXTENSION_LND CUST_EXT
ON (SPLIT.CUSTOMER_NUMBER = CUST_EXT.CUSTOMER_NUMBER AND SPLIT.EFF_DT = CUST_EXT.EFF_DT)
)
LEFT OUTER JOIN
(
SIGN_LND.T_CUSTOMER_CROSS_REF_LND XREF
LEFT OUTER JOIN
(
SELECT * FROM SIGN_LND.T_ALIAS_ACCT_NBR_CRSS_REF_LND WHERE EFF_DT = TO_DATE('2015-01-22','YYYY-MM-DD') AND ALIAS_ACCOUNT_NBR_TYPE = 'RB'
) RB_ALIAS_XREF
ON (XREF.ACCOUNT_NUMBER = RB_ALIAS_XREF.ACCOUNT_NUMBER AND XREF.EFF_DT = RB_ALIAS_XREF.EFF_DT)
LEFT OUTER JOIN
SIGN_LND.T_PRODUCT_OFFER_PURCHASE_LND PROD_OFFER
ON (XREF.BANK_NUMBER = PROD_OFFER.BANK_NUMBER AND XREF.ACCOUNT_NUMBER = PROD_OFFER.ACCOUNT_NUMBER AND XREF.EFF_DT = PROD_OFFER.EFF_DT)
)
ON (SPLIT.CUSTOMER_NUMBER = XREF.CUSTOMER_NUMBER AND SPLIT.EFF_DT = XREF.EFF_DT)
WHERE SPLIT.EFF_DT = TO_DATE('2015-01-22','YYYY-MM-DD')``
This should work
WITH query1 as
(your query 1 code),
query2 as
(you query 2 code),
query3 as
(your query 3 code)
select * from query1
join query2 on query1.Customer_number=query2.Customer_number
join query3 on query3.customer_number=query2.customer_number
and query3.account_number=query2.account_number
and query3.bank_number=query2.bank_number

Invoke a column twice with different conditions

I really appreciate any help with this matter :)
Am Working on a Report now and I had faced some troubles
I have this Query and it work fine , now I want to add a coulmn that is already exist in the query(from the same table) , but this time i'll change the condition of it , BTW the conditions in both of the 2 column are based on one other column
like for example If I have this :
Select Price from ITM1 WHERE PriceList = '1'
and also this
Select Price from ITM1 WHERE PriceList = '10'
how I can write in the same query and let them display in two different column ?
I will put the Query here in case if some one can help me through it :
you can see THE Column Price & PriceList in the lower part of it ,Bolded.
I just need to make the samething again but with a new coulmn name thats it.
Using the IN Operator will give you what you want. However, there are other changes that you can make to your query which would boost performance - but it's out of scope to the question. I'm unclear as to what you're trying to do with the different "columns" Please help explain. Else see #Dave.Gugg's answer which does just that.
SELECT T0.ItemCode,
T0.ItemName,
T0.CardCode,
T0.CodeBars,
T2.UgpCode,
T3.AltQty,
T3.BaseQty,
CASE
WHEN T4.Uomentry = - 1
THEN T0.[BuyUnitMsr]
ELSE t4.UomName
END AS 'UoMName',
T4.UomEntry,
T0.U_CAT_CODE,
T0.U_CAT_NAME,
T1.CardName,
(
SELECT TOP (1) dbo.PDN1.U_AC_QTY_ORDER
FROM dbo.PDN1
INNER JOIN dbo.OPDN ON dbo.PDN1.DocEntry = dbo.OPDN.DocEntry
WHERE (dbo.PDN1.ItemCode = T0.ItemCode)
AND (dbo.OPDN.CardCode = T0.CardCode)
ORDER BY dbo.OPDN.DocDate DESC
) AS OQuantity,
(
SELECT TOP (1) PDN1_1.U_AC_QTY_BONUS
FROM dbo.PDN1 AS PDN1_1
INNER JOIN dbo.OPDN AS OPDN_1 ON PDN1_1.DocEntry = OPDN_1.DocEntry
WHERE (PDN1_1.ItemCode = T0.ItemCode)
AND (OPDN_1.CardCode = T0.CardCode)
ORDER BY OPDN_1.DocDate DESC
) AS BQuantity,
ITM1.Price,
T0.U_DISC_PER
FROM dbo.OITM AS T0
INNER JOIN dbo.OCRD AS T1 ON T0.CardCode = T1.CardCode
INNER JOIN dbo.OUGP AS T2 ON T0.UgpEntry = T2.UgpEntry
INNER JOIN dbo.UGP1 AS T3 ON T2.UgpEntry = T3.UgpEntry
INNER JOIN dbo.ITM1 ON T0.ItemCode = dbo.ITM1.ItemCode
AND dbo.ITM1.PriceList IN ('1', '10')
LEFT JOIN dbo.OUOM AS T4 ON T3.UomEntry = T4.UomEntry
WHERE (T0.Series = '65')
AND (
T4.UomEntry = 3
OR T4.UomEntry = '-1'
)
If you want a different column (this may perform better than two joins):
SELECT T0.ItemCode,
T0.ItemName,
T0.CardCode,
T0.CodeBars,
T2.UgpCode,
T3.AltQty,
T3.BaseQty,
CASE
WHEN T4.Uomentry = - 1
THEN T0.[BuyUnitMsr]
ELSE t4.UomName
END AS 'UoMName',
T4.UomEntry,
T0.U_CAT_CODE,
T0.U_CAT_NAME,
T1.CardName,
(
SELECT TOP (1) dbo.PDN1.U_AC_QTY_ORDER
FROM dbo.PDN1
INNER JOIN dbo.OPDN ON dbo.PDN1.DocEntry = dbo.OPDN.DocEntry
WHERE (dbo.PDN1.ItemCode = T0.ItemCode)
AND (dbo.OPDN.CardCode = T0.CardCode)
ORDER BY dbo.OPDN.DocDate DESC
) AS OQuantity,
(
SELECT TOP (1) PDN1_1.U_AC_QTY_BONUS
FROM dbo.PDN1 AS PDN1_1
INNER JOIN dbo.OPDN AS OPDN_1 ON PDN1_1.DocEntry = OPDN_1.DocEntry
WHERE (PDN1_1.ItemCode = T0.ItemCode)
AND (OPDN_1.CardCode = T0.CardCode)
ORDER BY OPDN_1.DocDate DESC
) AS BQuantity,
CASE
WHEN ITM1.PriceList = '1'
THEN ITM1.Price
ELSE '0'
END AS Price1,
CASE
WHEN ITM1.PriceList = '10'
THEN ITM1.Price
ELSE '0'
END AS Price2,
T0.U_DISC_PER
FROM dbo.OITM AS T0
INNER JOIN dbo.OCRD AS T1 ON T0.CardCode = T1.CardCode
INNER JOIN dbo.OUGP AS T2 ON T0.UgpEntry = T2.UgpEntry
INNER JOIN dbo.UGP1 AS T3 ON T2.UgpEntry = T3.UgpEntry
INNER JOIN dbo.ITM1 ON T0.ItemCode = dbo.ITM1.ItemCode
AND dbo.ITM1.PriceList IN ('1', '10')
LEFT JOIN dbo.OUOM AS T4 ON T3.UomEntry = T4.UomEntry
WHERE (T0.Series = '65')
AND (
T4.UomEntry = 3
OR T4.UomEntry = '-1'
)
You should be able to just join to the table a second time, but you will need to make the joins outer:
SELECT T0.ItemCode ,
T0.ItemName ,
T0.CardCode ,
T0.CodeBars ,
T2.UgpCode ,
T3.AltQty ,
T3.BaseQty ,
CASE WHEN T4.Uomentry = -1 THEN T0.[BuyUnitMsr]
ELSE t4.UomName
END AS 'UoMName' ,
T4.UomEntry ,
T0.U_CAT_CODE ,
T0.U_CAT_NAME ,
T1.CardName ,
( SELECT TOP ( 1 )
dbo.PDN1.U_AC_QTY_ORDER
FROM dbo.PDN1
INNER JOIN dbo.OPDN ON dbo.PDN1.DocEntry = dbo.OPDN.DocEntry
WHERE ( dbo.PDN1.ItemCode = T0.ItemCode )
AND ( dbo.OPDN.CardCode = T0.CardCode )
ORDER BY dbo.OPDN.DocDate DESC
) AS OQuantity ,
( SELECT TOP ( 1 )
PDN1_1.U_AC_QTY_BONUS
FROM dbo.PDN1 AS PDN1_1
INNER JOIN dbo.OPDN AS OPDN_1 ON PDN1_1.DocEntry = OPDN_1.DocEntry
WHERE ( PDN1_1.ItemCode = T0.ItemCode )
AND ( OPDN_1.CardCode = T0.CardCode )
ORDER BY OPDN_1.DocDate DESC
) AS BQuantity ,
dbo.ITM1.Price ,
ITM1Second.Price,
T0.U_DISC_PER
FROM dbo.OITM AS T0
INNER JOIN dbo.OCRD AS T1 ON T0.CardCode = T1.CardCode
INNER JOIN dbo.OUGP AS T2 ON T0.UgpEntry = T2.UgpEntry
INNER JOIN dbo.UGP1 AS T3 ON T2.UgpEntry = T3.UgpEntry
LEFT OUTER JOIN dbo.ITM1 ON T0.ItemCode = dbo.ITM1.ItemCode
AND dbo.ITM1.PriceList = '10'
LEFT OUTER JOIN dbo.ITM1 ITM1Second ON T0.ItemCode = ITM1Second.ItemCode
AND ITM1Second.PriceList = '1'
LEFT OUTER JOIN dbo.OUOM AS T4 ON T3.UomEntry = T4.UomEntry
WHERE ( T0.Series = '65' )
AND ( T4.UomEntry = 3
OR T4.UomEntry = '-1'
)