Best Join Strategy/Indexes for SQL Server - sql

What is the best join strategy/indexes for this query:
SELECT
kwk.*, an.AuftragDatum, an.AbgabeDatum, an.BezahltDatum, an.AuftragStatus
FROM
KundenWerbenKunden kwk
INNER JOIN
Auftrag an ON an.AuftragNummer = kwk.AuftragNummer
WHERE
kwk.Deleted = 0
Table KundenWerbenKunden has 103950 rows with 103646 Deleted = 0 ones.
Table Auftrag has 3826552 rows.
In my real query I make some more joins:
INNER JOIN
Filiale fn WITH (NOLOCK) ON an.FilialeID = fn.FilialeID
INNER JOIN
Kunde kn ON an.KundeID = kn.KundeID
OUTER APPLY
(SELECT DISTINCT KSKNr
FROM KdZuordnung
WHERE KundeID = kn.KundeID) zn
LEFT JOIN
Anrede ann WITH (NOLOCK) ON kn.Anrede = ann.Anrede
INNER JOIN
AuftragArt aa WITH (NOLOCK) ON an.AuftragArtID = aa.AuftragArtID
INNER JOIN
AuftragGrund ag WITH (NOLOCK) ON an.AuftragGrundID = ag.AuftragGrundID
INNER JOIN
AuftragType at WITH (NOLOCK) ON an.AuftragTypeID = at.AuftragTypeID

For this query:
SELECT *
FROM KundenWerbenKunden kwk INNER JOIN
Auftrag an
ON an.AuftragNummer = kwk.AuftragNummer
WHERE kwk.Geloescht = 0;
And not knowing anything about the distribution of Geloescht, I would first try indexes on KundenWerbenKunden(Geloescht, AuftragNummer) and Auftrag(AuftragNummer).

Related

summation in sql

I have a query result tabletable of result i would like to sum the bill amount such that it returns one row with a distinct account ,balance,sum billed amount fPreviousReading,
fCurrentReading,
fConsumption .
result should be
1.account 11074
2.balance269.49
3.sumbilledamount 520.48
4. fPreviousReading 574
5 fCurrentReading 612
6 fConsumption 38
Thanks
query
select
Ten.Account,
ten.DCBalance AS Balance,
SUM(T.fInclusiveAmount)AS BilledAmount,
MRD.fPreviousReading,
MRD.fCurrentReading ,
MRD.fConsumption ,
T.cDescription
from _mtblTransactions T
left join _mtblProperties P ON P.idProperty = T.iPropertyID
left join _mtblPropertyPortions PP ON PP.idPropertyPortions = T.iPortionID
left join _mtblPropertyPortionServices PPS ON PPS.idPropertyPortionServices = T.iPropertyPortionServiceID
left join _mtblCategories Cat ON Cat.idCategory = PP.iPortionUsageID
left join _mtblServices S ON PPS.iPortionServiceID = S.idService
left join _mtblServiceGroups SG ON S.iServiceGroupID = SG.idServiceGroup
left join _mtblRateTariffs RT ON RT.idRateTariffs = PPS.iServiceRateTariffID
left join Client Ten ON T.iCustomerID = Ten.DCLink
left join _mtblMeters M ON PPS.iPropertyPortionMeterID = M.idMeter
left join _mtblWalkDetails WD ON WD.iWalkMeterID = PPS.iPropertyPortionMeterID
left join _mtblWalks W ON WD.iWalkID = W.idWalk
left join Client Own ON P.iPropertyOwnerID = Own.DCLink
left outer join _mtblRegions R on R.idRegions = P.iPropertyRegionID
left outer join _mtblSubRegions SR on SR.idSubRegions = P.iPropertySubRegionID
left outer join _mtblAreas A on A.idAreas = P.iPropertyAreaID
left join _etblPeriod PER ON T.iPeriodID = PER.idPeriod
left join _mtblMeterReadingDetails MRD ON T.iMeterID = MRD.iMeterReadingsMeterID and T.iPeriodID = MRD.iBillingPeriodID
and MRD.iReadingType=0
Where
oWN.Account='11074'
and idPeriod='79'
GROUP BY Ten.Account,ten.DCBalance,MRD.fPreviousReading, MRD.fCurrentReading, MRD.fConsumption, T.cDescription
As I don't know your data, there is a possibility I wrote you a code that would return some double rows. But that is a problem you can easily handle.
Try it, nevertheless:
SELECT t1.Account,
t1.Balance,
t1.BilledAmount,
t1.fPreviousReading,
t1.fCurrentReading,
t1.fConsumption,
t2.cDescription
FROM (SELECT Ten.Account,
ten.DCBalance AS Balance,
SUM (T.fInclusiveAmount) AS BilledAmount,
SUM (MRD.fPreviousReading) AS fPreviousReading,
SUM (MRD.fCurrentReading) AS fCurrentReading,
SUM (MRD.fConsumption) AS fConsumption
FROM _mtblTransactions T
left join _mtblProperties P ON P.idProperty = T.iPropertyID
left join Client Ten ON T.iCustomerID = Ten.DCLink
left join Client Own ON P.iPropertyOwnerID = Own.DCLink AND oWN.Account='11074'
left join _etblPeriod PER ON T.iPeriodID = PER.idPeriod
left join _mtblMeterReadingDetails MRD ON T.iMeterID = MRD.iMeterReadingsMeterID and T.iPeriodID = MRD.iBillingPeriodID
and MRD.iReadingType=0
and idPeriod='79'
GROUP BY Ten.Account,ten.DCBalance) t1
JOIN (SELECT T.cDescription,
Ten.Account,
ten.DCBalance
FROM _mtblTransactions T
left join Client Ten ON T.iCustomerID = Ten.DCLink) t2 ON t2.Account = t1.Account AND t2.DCBalance = t1.DCBalance

How to get rid of duplicating data in every row?

SELECT distinct AD.ReferenceNumber, AD.ProjectTitle, Z.ZoneCode, C.CompanyName,SS.AssignedTo, ZG.ZoneGroupName,au.Amount
FROM ApplicationDetails AD
LEFT JOIN ApplicationFormsDetails AS b ON (AD.referencenumber = b.referencenumber)
LEFT JOIN ScheduleSummaries AS SS ON (AD.ReferenceNumber = SS.ReferenceNo)
INNER JOIN AppTypes as at on ss.ItemCode = at.Category
INNER JOIN Companies AS C ON (AD.CompanyId = C.CompanyID)
INNER JOIN Zones Z ON (C.ZoneCode = Z.ZoneCode)
INNER JOIN ZoneGroups ZG ON (Z.ZoneGroup = ZG.ZoneGroupId)
LEFT JOIN AssessmentUsedItems au on ah.AssessmentHeaderId = au.HeaderId
WHERE AD.ApplicationDate BETWEEN '2017-10-01' AND '2017-10-31' AND ZG.ZoneGroupCode = 'HO' and ah.referencenumber = 'N-101317-A1-02'
GROUP BY AD.ReferenceNumber, AD.ProjectTitle, Z.ZoneCode, C.CompanyName,SS.AssignedTo, ZG.ZoneGroupName,au.Amount--, ah.ApplicationForm,au.Amount
The output of this query is its duplicating the amount for every AssignTO.
Output :
Maybe you want to try using SUM(ISNULL(au.amount, 0)) AS amount instead of au.amount and remove au.amount from the GROUP BY as well...
Try this query:
SELECT AD.ReferenceNumber,
AD.ProjectTitle,
Z.ZoneCode,
C.CompanyName,
SS.AssignedTo,
ZG.ZoneGroupName,
SUM(COALESCE(au.Amount,0)) AS Amount
FROM ApplicationDetails AD
LEFT JOIN ApplicationFormsDetails AS b
ON (AD.referencenumber = b.referencenumber)
LEFT JOIN ScheduleSummaries AS SS
ON (AD.ReferenceNumber = SS.ReferenceNo)
INNER JOIN AppTypes AS at
ON ss.ItemCode = at.Category
INNER JOIN Companies AS C
ON (AD.CompanyId = C.CompanyID)
INNER JOIN Zones Z
ON (C.ZoneCode = Z.ZoneCode)
INNER JOIN ZoneGroups ZG
ON (Z.ZoneGroup = ZG.ZoneGroupId)
LEFT JOIN AssessmentUsedItems au
ON ah.AssessmentHeaderId = au.HeaderId
WHERE AD.ApplicationDate BETWEEN '2017-10-01' AND '2017-10-31'
AND ZG.ZoneGroupCode = 'HO'
AND ah.referencenumber = 'N-101317-A1-02'
GROUP BY
AD.ReferenceNumber,
AD.ProjectTitle,
Z.ZoneCode,
C.CompanyName,
SS.AssignedTo,
ZG.ZoneGroupName

why selecting particular columns from same table slows down query performance significantly?

I have SELECT statement that querying columns from tblQuotes. Why if I am selecting columns a.ProducerCompositeCommission and a.CompanyCompositeCommission, then query spinning forever.
Execution plans with and without those columns are IDENTICAL!
If I commented them out - then it brings result for 1 second.
SELECT
a.stateid risk_state1,
--those columns slows down performance
a.ProducerCompositeCommission,
a.CompanyCompositeCommission,
GETDATE() runDate
FROM
tblQuotes a
INNER JOIN
lstlines l ON a.LineGUID = l.LineGUID
INNER JOIN
tblSubmissionGroup tsg ON tsg.SubmissionGroupGUID = a.SubmissionGroupGuid
INNER JOIN
tblUsers u ON u.UserGuid = tsg.UnderwriterUserGuid
INNER JOIN
tblUsers u2 ON u2.UserGuid = a.UnderwriterUserGuid
LEFT OUTER JOIN
tblFin_Invoices tfi ON tfi.QuoteID = a.QuoteID AND tfi.failed <> 1
INNER JOIN
lstPolicyTypes lpt ON lpt.policytypeid = a.policytypeid
INNER JOIN
tblproducercontacts prodC ON prodC.producercontactguid = a.producercontactguid
INNER JOIN
tblProducerLocations pl ON pl.producerlocationguid = prodc.producerlocationguid
INNER JOIN
tblproducers prod ON prod.ProducerGUID = pl.ProducerGUID
LEFT OUTER JOIN
Catalytic_tbl_Model_Analysis aia ON aia.ImsControl = a.controlno
AND aia.analysisid = (SELECT TOP 1 tma2.analysisid
FROM Catalytic_tbl_Model_Analysis tma2
WHERE tma2.imscontrol = a.controlno)
LEFT OUTER JOIN
Catalytic_tbl_RDR_Analysis rdr ON rdr.ImsControl = a.controlno
AND rdr.analysisid = (SELECT TOP 1 tma2.analysisid
FROM Catalytic_tbl_RDR_Analysis tma2
WHERE tma2.imscontrol = a.controlno)
LEFT OUTER JOIN
tblProducerContacts mnged ON mnged.producercontactguid = ProdC.ManagedBy
LEFT OUTER JOIN
lstQuoteStatusReasons r1 ON r1.id = a.QuoteStatusReasonID
WHERE
l.LineName = 'EARTHQUAKE'
AND CAST(a.EffectiveDate AS DATE) >= CAST('2017-01-01' AS DATE)
AND CAST(a.EffectiveDate AS DATE) <= CAST('2017-12-31' AS DATE)
ORDER BY
a.effectiveDate
The execution plan can be found here:
https://www.brentozar.com/pastetheplan/?id=rJawDkTx-
I ran sp_help and this is what I see:
What exactly wrong with those columns?
I dont use them in a JOIN or anything. Why such bahaviour?
Table Size:
Indexes on table tblQuotes

Problems with Sql query join

I am struggling with a sql query. I want to include the sum from an other table.
SELECT DISTINCT
tblProject.CompanyID,
tblCompany.Name,
tblCompany.AvtalsKund,
tblProject.ProjectName,
tblProject.Estimate,
tblProject.ProjectStart,
tblProject.Deadline,
CONVERT(VARCHAR(8), tblProject.Deadline, 2) AS [YY.MM.DD] ,
tblProject.PreOffered,
tblProject.ProjectType,
tblProjectType.ProjType,
tblOrdered.FirstName + + tblOrdered.LastName as OrderedFullName,
tblProject.ProjectID,
tblProject.RegDate,
tblProject.ProjectNr,
tblProject.ProjectNr
FROM tblProject
INNER JOIN tblCompany ON tblProject.CompanyID = tblCompany.CompanyID
---> INNER JOIN (SELECT tblTimeRecord.ProjectID, SUM(CONVERT(float,replace([Hours],',','') ))
FROM tblTimeRecord group by tblTimeRecord.ProjectID) as b
ON b.ProjectID = tblProject.ProjectID
INNER JOIN tblTimeRecord ON tblTimeRecord.ProjectID = tblProject.ProjectID
INNER JOIN tblProjectType ON tblProject.ProjectType = tblProjectType.ProjTypeID
LEFT OUTER JOIN tblOrdered ON tblProject.OrderedBy = tblOrdered.OrderedID
LEFT OUTER JOIN tblRel_WorkerProject ON tblProject.ProjectID = tblRel_WorkerProject.ProjectID
LEFT OUTER JOIN tblPerson ON tblPerson.PersonID = tblRel_WorkerProject.WorkerID
LEFT OUTER JOIN tblRel_StatusWorkerProject ON tblProject.ProjectID = tblRel_StatusWorkerProject.ProjectID
I want to include this sum-block from table tblTimeRecord.
I get a sum of timerapports with this code
SELECT tblTimeRecord.ProjectID,
SUM(CONVERT(float,replace([Hours],',','') ))
FROM tblTimeRecord where ProjectID=1312 group by tblTimeRecord.ProjectID
Guess i do it in join?
Got it working with this.
SELECT DISTINCT
tblProject.ProjectID,
Summa,
tblProject.CompanyID,
tblCompany.Name,
tblCompany.AvtalsKund,
tblProject.ProjectName,
tblProject.Estimate,
tblProject.ProjectStart,
tblProject.Deadline,
CONVERT(VARCHAR(8), tblProject.Deadline, 2) AS [YY.MM.DD] ,
tblProject.PreOffered,
tblProject.ProjectType,
tblProjectType.ProjType,
tblOrdered.FirstName + + tblOrdered.LastName as OrderedFullName,
tblProject.ProjectID,
tblProject.RegDate,
tblProject.ProjectNr,
tblProject.ProjectNr
FROM tblProject
INNER JOIN tblCompany ON tblProject.CompanyID = tblCompany.CompanyID
INNER JOIN (SELECT tblTimeRecord.ProjectID, SUM(CONVERT(float,replace([Hours],',','') )) as Summa FROM tblTimeRecord group by tblTimeRecord.ProjectID) as b
ON b.ProjectID = tblProject.ProjectID
INNER JOIN tblTimeRecord ON tblTimeRecord.ProjectID = tblProject.ProjectID
INNER JOIN tblProjectType ON tblProject.ProjectType = tblProjectType.ProjTypeID
LEFT OUTER JOIN tblOrdered ON tblProject.OrderedBy = tblOrdered.OrderedID
LEFT OUTER JOIN tblRel_WorkerProject ON tblProject.ProjectID = tblRel_WorkerProject.ProjectID
LEFT OUTER JOIN tblPerson ON tblPerson.PersonID = tblRel_WorkerProject.WorkerID
LEFT OUTER JOIN tblRel_StatusWorkerProject ON tblProject.ProjectID = tblRel_StatusWorkerProject.ProjectID
There are two ways to do this.
You can use a WITH clause to create the aggregate table then join this to the main query.
Or do it this way:
SELECT m.BLAH
,m.FOO
,x.AMOUNT
FROM MAINTABLE m
LEFT JOIN
(
SELECT FOO
,SUM(AMOUNT) as AMOUNT
FROM OTHERTABLE
GROUP BY FOO
) x
ON m.FOO = x.FOO
I prefer the second way.

Inner join more than 2 tables in a single database

i want to innerjoin more than 3 tables in one select query in one database all of them are having rm_id as a common column but i want to display the rows of all tables in one sql query is it possible if it is then i would hearly request u to provide some code
select * from
bk_det inner join
bk_rep inner join
bk_sec inner join
mut_det inner join
rm_det inner join
soil_det
on
bk_det.rm_id = bk_rep.rm_id = bk_sec.rm_id = mut_det.rm_id = rm_det.rm_id = soil_det.rm_id
You need an on clause for each inner join. e.g.
select * from a
inner join b on a.id = b.id
inner join c on b.id = c.id
You are missing the ON clause for each join:
select *
from bk_det
inner join bk_rep
on bk_det.rm_id = bk_rep.rm_id
inner join bk_sec
on bk_rep.rm_id = bk_sec.rm_id
inner join mut_det
on bk_sec.rm_id = mut_det.rm_id
inner join rm_det
on mut_det.rm_id = rm_det.rm_id
inner join soil_det
on rm_det.rm_id = soil_det.rm_id
Note: you will have to check the join condition column names since I do not know your table structure
If you need help with learning join syntax, here is a great visual explanation of joins.
Since you are using an INNER JOIN this will return records if the rm_id exists in each table.
You might need to use a LEFT JOIN:
select *
from bk_det
left join bk_rep
on bk_det.rm_id = bk_rep.rm_id
left join bk_sec
on bk_rep.rm_id = bk_sec.rm_id
left join mut_det
on bk_sec.rm_id = mut_det.rm_id
left join rm_det
on mut_det.rm_id = rm_det.rm_id
left join soil_det
on rm_det.rm_id = soil_det.rm_id