Improve SQL Server conditional join - sql-server

Is correct to put these conditional sentences in join statement in order to improve performance?
I just tried to use same code using one union and cross apply per condition used, but when I use the code in other queries, is too slow.
SELECT u2.fkPropertyID, u2.pkUnitId, u2.UnitCode,
u2.fkUnitViewID,u2.fkFloorPlanID, u2.fkCalendarTypeID
FROM dbo.tblUnit u
left join dbo.tblUnitGroup ug ON ug.fkUnitLogicalID = u.pkUnitID
left JOIN dbo.tblUnit u2 on ((u2.fkUnitGroupID = u.pkUnitID and
u.ynPhyUnit = 0)
or
(u2.pkUnitID = u.pkUnitID and u2.ynPhyUnit =1))
or
(u2.pkUnitId = ug.fkUnitPhisicallID and u2.ynPhyUnit = 1)
where u.pkUnitId = 3806

Just for fun here is one way you could rewrite this. I suspect if you look at the execution plan it will be identical.
SELECT u2.fkPropertyID
, u2.pkUnitId
, u2.UnitCode
, u2.fkUnitViewID
, u2.fkFloorPlanID
, u2.fkCalendarTypeID
FROM dbo.tblUnit u
left join dbo.tblUnitGroup ug ON ug.fkUnitLogicalID = u.pkUnitID
left JOIN dbo.tblUnit u2 on
(
u2.fkUnitGroupID = u.pkUnitID
and
u.ynPhyUnit = 0
)
or
(
u2.pkUnitID in (u.pkUnitID, ug.fkUnitPhisicallID)
and
u2.ynPhyUnit = 1
)
where u.pkUnitId = 3806

I get this with best results in execution plan, I am reviewing with other values:
SELECT u2.fkPropertyID, u2.pkUnitId, u2.UnitCode, u2.fkUnitViewID,
u2.fkFloorPlanID, u2.fkCalendarTypeID
FROM tblUnit u
left join dbo.tblUnitGroup ug ON ug.fkUnitLogicalID = u.pkUnitID
outer apply
(
select uu2.fkPropertyID, uu2.pkUnitId, uu2.UnitCode,
uu2.fkUnitViewID, uu2.fkFloorPlanID, uu2.fkCalendarTypeID
from dbo.tblUnit uu2
where ( ((uu2.fkUnitGroupID = u.pkUnitID) and (u.ynPhyUnit = 0))
or
((uu2.pkUnitID = u.pkUnitID) and (uu2.ynPhyUnit = 1)) )
or
( (uu2.pkUnitId = ug.fkUnitPhisicallID) and (uu2.ynPhyUnit = 1) )
) as u2
where u.pkUnitId = 3806

Related

SQLServer 2014 unable to achieve parallelism for query

I use SQLServer 2014 (120 compatibility mode) and I want a parallel execution plan for my query, but because of a few fields, it isn't. As long as field pi.Name AS ProcessName is commented I have parallelism but when it is active it isn't. The same problem is with other commented fields. Is the reason connected with an index which covers pi.ProcessGuid but not pi.Name or something more?
ExecutionPlan_Parallel
ExecutionPlan_Single
ExecutionPlan_Original
When I commented on those few fields ExecutionPlan starts to be parallel and from 30 minutes query runs only 11 seconds.
SELECT kg.Id,
ui.UserInfoGuid AS UserGuid,
ui.FullName AS UserName,
di.DeviceInfoGuid AS DeviceGuid,
di.ComputerFullName,
pi.ProcessGuid,
--pi.Name AS ProcessName,
kg.ProcessActivationGuid,
t.Caption,
whi.WebsiteHostGuid,
--whi.HostName,
wv.WebsiteGuid,
wv.[Url],
--cc.CategoryGuid,
--cc.[Name] AS CategoryName,
ca.ControlSequenceGuid,
ca.ControlActivationGuid/*
(SELECT ce.[Name] + '/' AS [text()]
FROM [raw].ControlElement AS ce
WHERE ce.ControlSequenceGuid = ca.ControlSequenceGuid
ORDER BY ce.SequenceNumber DESC
FOR xml path ('')) AS ControlTree*/
--,ac.ApplicationContextName
,kg.BeginDate AS KeystrokeBeginDate
,kg.EndDate AS KeystrokeEndDate
,kg.TotalKeyCount
,kg.KeyCount
,kg.FunctionalKeyCount
,kg.ClickCount
,kg.WheelCount
,kg.OtherKeyCount
,kg.TotalMilliseconds
,kg.ActiveMilliseconds
FROM raw.[Session] AS s
INNER JOIN raw.Monitoring AS m
ON ( m.SessionGuid = s.SessionGuid )
INNER JOIN stats.[KeystrokeGroupRcpView] AS kg
ON ( kg.MonitoringGuid = m.MonitoringGuid )
INNER JOIN dbo.UserInfo AS ui
ON ( ui.UserInfoGuid = kg.UserGuid )
INNER JOIN dbo.DeviceInfo AS di
ON ( di.DeviceInfoGuid = kg.DeviceGuid )
INNER JOIN dbo.ProcessInfo AS pi
ON ( pi.OrganizationGuid = di.OrganizationGuid
AND pi.ProcessGuid = kg.ProcessGuid )
INNER JOIN raw.Title AS t
ON ( t.TitleGuid = kg.TitleGuid )
LEFT OUTER JOIN [raw].ControlActivation AS ca
ON ca.ProcessActivationGuid = kg.ProcessActivationGuid
AND kg.BeginDate >= ca.BeginDate
AND kg.EndDate <= ca.EndDate
LEFT OUTER JOIN controls.ControlFocus AS cf
ON cf.ControlActivationGuid = ca.ControlActivationGuid
LEFT OUTER JOIN controls.ControlSequenceContext AS csc
ON csc.ControlSequenceGuid = ca.ControlSequenceGuid
LEFT OUTER JOIN controls.ApplicationContext AS ac
ON ac.ApplicationContextGuid = csc.ApplicationContextGuid
LEFT OUTER JOIN controls.ProcessControlCategory AS pcc
ON pcc.ProcessGuid = pi.ProcessGuid
AND pcc.ControlCategoryKeyGuid =
cf.ControlCategoryKeyGuid
LEFT OUTER JOIN controls.ControlCategory AS cc
ON cc.CategoryGuid = pcc.CategoryGuid
LEFT OUTER JOIN raw.WebsiteVisit AS wv
ON ( pi.IsWebBrowser = 1
AND wv.ProcessActivationGuid =
kg.ProcessActivationGuid
AND ( wv.BeginDate < kg.BeginDate
AND wv.EndDate >= kg.EndDate ) )
LEFT OUTER JOIN dbo.WebsiteHostInfo AS whi
ON ( whi.WebsiteHostGuid = wv.WebsiteHostGuid
AND whi.OrganizationGuid = di.OrganizationGuid )
WHERE kg.BeginDate > '2020-07-01' AND kg.BeginDate < '2020-07-02' and kg.UserGuid in ('A170565A-2D30-4911-5B9C-8525E2A2772B','4BE982BD-ADFC-6201-31C2-60A0BEF0D7F6','AE296576-87C6-EC2F-5A6F-E24ACE14456E')

optimize the query, my query taking more than 5 minutes to execute

my query taking more than 5 minutes to execute can anyone tell me what's wrong in this query, below is the query I try to optimize it but no luck
SELECT DISTINCT
'Freight' AS Expr1000,
'Acknowledged Trip Details' AS detailtype,
sCompanyDesc,
VehicleRegistration.sVehicleRegistrationNumber,
Token.iTokenId,
sTokenNumber,
Token.dtTokenGenerating AS TokenDate,
LoadAssign.sCustomerInvoiceNumber,
dtCustomerInvoiceDate,
FillingPoint.sFillingPointName AS [From],
DecantingPoint.sDecantingPointName AS [To],
CloseLoad.fExpectedFreightAmount AS fExpectedFreightAmount,
ISNULL(PayAdvance.fAdvanceAmount, 0) AS fAdvanceAmount,
CloseLoad.fCommissionAmount AS fCommissionAmount,
CloseLoad.fDecantedQuantity,
0 AS [Shortage Quantity],
0 AS [Shortage Rate],
0 AS [Shortage Amount],
sProductName,
ISNULL((SELECT SUM(ISNULL(JVDetails.fCreditAmount, 0))
FROM Transactions
INNER JOIN JV ON JV.sJVCode = Transactions.sTransactionCode
INNER JOIN JVDetails ON JVDetails.iJVId = JV.iJVId
WHERE CloseLoad.iTokenId = Transactions.iTokenId
AND JV.sDescription = 'Munshiana'),
0) AS Munshiana,
ISNULL(JV.sJVCode, '') + ISNULL(PV.sPVCode, '') AS advdocnum
FROM CloseLoad
INNER JOIN Token ON CloseLoad.iTokenId = Token.iTokenId
INNER JOIN LoadAssign ON CloseLoad.iLoadId = LoadAssign.iLoadId
INNER JOIN FillingPoint ON Token.iFillingPointId = FillingPoint.iFillingPointId
INNER JOIN DecantingPoint ON LoadAssign.iDecantingPointId = DecantingPoint.iDecantingPointId
INNER JOIN Product ON LoadAssign.iProductId = Product.iProductId
INNER JOIN VehicleRegistration ON Token.iVehicleRegistrationId = VehicleRegistration.iVehicleRegistrationId
INNER JOIN Company ON Token.iCompanyId = Company.iCompanyId
LEFT JOIN PayAdvance ON PayAdvance.iTokenId = Token.iTokenId
AND PayAdvance.bIsApproved = 1
LEFT JOIN PV ON PV.iPayAdvanceId = PayAdvance.iPayAdvanceId
AND PayAdvance.bIsApproved = 1
AND PV.bIsApproved = 1
LEFT JOIN JV ON JV.iPayAdvanceId = PayAdvance.iPayAdvanceId
AND PayAdvance.bIsApproved = 1
AND JV.bIsApproved = 1
WHERE CloseLoad.iLoadId NOT IN (SELECT tfrli.iLoadId
FROM TempFreightReceiptLoadInfo tfrli
INNER JOIN FreightReceiptChqInfo ci ON ci.iFreightReceiptChqInfoId = tfrli.iFreightReceiptChqInfoId
INNER JOIN LoadAssign l1 ON l1.iLoadId = tfrli.iLoadId
WHERE ci.bIsApproved = 1
AND l1.dtCustomerInvoiceDate BETWEEN '8/1/2020' AND '8/30/2020'
AND tfrli.sAllocationType = 'Freight')
AND LoadAssign.bIsLoadClose = 1
AND Token.iVehicleRegistrationId = 2644
AND LoadAssign.dtCustomerInvoiceDate BETWEEN '8/1/2020' AND '8/30/2020'
AND Token.iCompanyId IN (1, 2, 3)
AND Token.sDecantingPointType IN ('Domestic', 'Export')
AND LoadAssign.bIsActive = 1
AND Token.bIsLoadVerify = 1;
Execute EXPLAIN to find bottleneck.
EXPLAIN SELECT DISTINCT ...

SQL Server CASE WHEN in WHERE clause

I have a query with some joins. One of the joins depends of another value.
This is my query:
SELECT *
FROM CLIIRE A
LEFT JOIN CLIIOR B ON A.PTA = B.PTA AND A.ORD = B.ORD AND A.ITE = B.ITE
LEFT JOIN CLIORD C ON C.PTA = B.PTA AND C.ORD = B.ORD
LEFT JOIN CLIPAC D ON C.OPA = D.ORI AND C.PAC = D.PAC
LEFT JOIN CLIREN E ON E.NRE = A.NRE AND D.INS = E.INS AND A.CPT = E.CPT
LEFT JOIN
(SELECT *
FROM CLINOM
WHERE CLA = (CASE WHEN B.PFA = '88882' THEN 'MD' ELSE 'BU' END )) AS N ON B.PFA = N.COD
LEFT JOIN
(SELECT *
FROM CLIMED WHERE PRE = '') AS M ON B.PFA = M.MED
LEFT JOIN CLIPRF P ON B.PRF = P.PRF
WHERE
(D.INS LIKE 'OM%' OR D.INS LIKE 'SOL%')
AND E.NFA IN ('5188')
AND A.CPT IN ('fi', 'pi')
ORDER BY
E.NFA
But I'm getting error in the line:
LEFT JOIN (SELECT * FROM CLINOM WHERE CLA = (CASE WHEN B.PFA = '88882' THEN 'MD' ELSE 'BU' END )) AS N ON B.PFA=N.COD
Looks like SQL Server won't allow me to do that:
The multi-part identifier "B.PFA" could not be bound
The column B.PFA exists.
Can anyone help me? Thanks !
The problem is that the outer query reference is not available in the subquery. Happily, though the subquery is not needed. Try this logic:
LEFT JOIN CLINOM N
ON P.FA = N.COD AND
N.CLA = (CASE WHEN B.PFA = '88882' THEN 'MD' ELSE 'BU' END)
And, you can phrase this without the CASE. Assuming B.PFA is not NULL:
LEFT JOIN CLINOM N
ON P.FA = N.COD AND
((N.CLA = 'MD' AND B.PFA = '88882') OR
(N.CLA = 'BU' AND B.PFA <> '88882')
)
If B.PFA could be NULL:
LEFT JOIN CLINOM N
ON P.FA = N.COD AND
((N.CLA = 'MD' AND B.PFA = '88882') OR
(N.CLA = 'BU' AND (B.PFA <> '88882' OR B.PFS IS NULL))
)
You can also use COALESCE() if you like.

sql query assistance

I have a sql that is as under:
SELECT ib.branch_no,
ib.on_hand,
p.weightedav,
p.item_code,
FROM physical p
INNER JOIN
item_branch as ib on p.item_code = ib.item_code
WHERE ib.on_hand <> 0
This SQL returns only those branch_no that have on_hand <> 0.
I am trying to get all the branch_nos irrespective of the on_hand field, but while still using the where on_hand clause.
Taking the on_hand clause away solves my problem, but gives me large amount of un-needed rows with 0's.
I am using SQL SERVER 2008 R2.
Thanks in advance for any guidance. Please apologize if I am missing any information.
------------------------------------------ENTIRE SQL QUERY (Updated)---------------------------------------------
select
ib.branch_no,
p.weighted_av,
p.item_code,
p.x_value,
p.y_value,
ib.on_hand,
p.on_hand as PhysicalOH,
ip.price,
i.item_code as StyleCode,
i.description,
i.cat1,
i.cat2,
i.cat3,
i.cat4,
np.is_style_yn,
si.supplier_code ,
ysv.sort as YSort
from physical as p
left outer JOIN
item_branch as ib on p.item_code = ib.item_code -- and ib.on_hand <> 0
INNER JOIN
item_price as ip on p.item_code = ip.item_code and ip.price_type = 'P1'
INNER JOIN
style_values as sv on p.style_code = sv.style_code and p.x_value = sv.value
INNER JOIN
style_values as ysv on p.style_code = ysv.style_code and p.y_value = ysv.value and ysv.axis = 'Y'
INNER JOIN
ITEM as i on p.style_code = i.item_code
INNER JOIN
NON_PHYSICAL as np ON i.item_code = np.item_code and np.is_style_yn = 1
INNER JOIN
supplier_item as si ON i.item_code = si.item_code and si.pref_supp_no = 1
where --ib.on_hand <> 0 and
sv.axis = 'X' and
i.item_code in
(SELECT ITEM.item_code
FROM ITEM
INNER JOIN
NON_PHYSICAL ON ITEM.item_code = NON_PHYSICAL.item_code
LEFT JOIN
supplier_item ON Item.item_code = supplier_item.item_code and pref_supp_no = 1
WHERE NON_PHYSICAL.is_style_yn = 1 and ITEM.cat1 = 'Verge Sportswear Ltd' )
order by
si.supplier_code,
i.cat4,
i.cat3,
i.cat2,
i.cat1,
sv.sort
Try this:
SELECT ib.branch_no,
ib.on_hand,
p.weightedav,
p.item_code,
FROM physical p
INNER JOIN
item_branch as ib on (p.item_code = ib.item_code AND ib.on_hand <> 0)

JOIN codition in SQL Server

After applying join condition on two tables I want records which is maximum among records of left table
My query
SELECT a1.*,
t.*,
( a1.trnratefrom - t.trnratefrom )AS minrate,
( a1.trnrateto - t.trnrateto ) AS maxrate
FROM (SELECT a.srno,
trndate,
b.trnsrno,
Upper(Rtrim(Ltrim(b.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(b.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(b.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(b.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(b.trnunit))) AS trnunit,
b.trnratefrom,
b.trnrateto,
a.remark,
entdate
FROM mstprodrates a
INNER JOIN trnprodrates b
ON a.srno = b.srno)a1
INNER JOIN (SELECT c.srno,
trndate,
d.trnsrno,
Upper(Rtrim(Ltrim(d.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(d.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(d.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(d.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(d.trnunit))) AS trnunit,
d.trnratefrom,
d.trnrateto,
c.remark,
entdate
FROM mstprodrates c
INNER JOIN trnprodrates d
ON c.srno = d.srno) AS t
ON a1.trnstate = t.trnstate
AND a1.trnquality = t.trnquality
AND a1.trnunit = t.trnunit
AND a1.trnlength = t.trnlength
AND a1.trnarea = t.trnarea
AND a1.remark = t.remark
WHERE t.srno = (SELECT MAX(srno)
FROM a1
WHERE srno < a1.srno)
If you mean to say,
you want Records exist in Left table but not in right then use LEFT OUTER JOIN.

Resources