SUM and ORDER BY - sql

I have this table
Pupil ID Fname Lname Form House Week Nr Data
104 fname1 lname1 Year 5W Junior Frobisher 3 5
106 fname2 lname2 Year 4W Junior Grenville 2 5
106 fname2 lname2 Year 4W Junior Grenville 3 4
106 fname2 lname2 Year 4W Junior Grenville 4 3
106 fname2 lname2 Year 4W Junior Grenville 5 5
107 fname3 lname3 Year 5W Junior Grenville 1 1
107 fname3 lname3 Year 5W Junior Grenville 2 3
107 fname3 lname3 Year 5W Junior Grenville 3 5
107 fname3 lname3 Year 5W Junior Grenville 4 1
SELECT PPD.PupilID, PPD.Forename, PPD.Surname, FL.[Description] AS 'Form', HL.[Description] AS 'House', CAST(REPLACE(CM.ColumnTitle, 'Week ', '') AS INT) AS 'WeekNo',CAST(MSDN.Data AS INT) AS 'Data', SUM(CAST(MSDN.Data AS INT)) AS 'Total'
FROM CurrentPupil
INNER JOIN PupilPersonalDetails AS PPD ON PPD.PupilID = CurrentPupil.PupilID
INNER JOIN PupilCurrentSchool AS PCS ON PCS.PupilID = PPD.PupilID
INNER JOIN SchoolLookupDetails AS FL ON PCS.Form = FL.LookupDetailsID AND FL.LookupID = 1002
INNER JOIN SchoolLookupDetails AS HL ON PCS.House = HL.LookupDetailsID AND HL.LookupID = 1001
INNER JOIN MarksheetDataNumeric AS MSDN ON MSDN.PupilID = PPD.PupilID
INNER JOIN ColumnsMaster AS CM ON CM.ColumnID = MSDN.ColumnID AND CM.ColumnTitle LIKE '%week%'
INNER JOIN ClusterMaster AS CLM ON CLM.ClusterID = SUBSTRING(PPD.SchoolID, 0, 4)
INNER JOIN ColumnReportingPeriods AS CRP ON CRP.ColumnID = CM.ColumnID
INNER JOIN ReportingPeriods AS RP ON RP.AcademicYear = CLM.CurrentAcademicYear AND RP.ReportingPeriodID = CRP.ReportingPeriodID
WHERE ('%wc%' = '%wc%')
GROUP BY PPD.PupilID
I am trying to SUM the following column
CAST(MSDN.Data AS INT) AS 'Data'
and add a new one as a total points for each ID (pupil)
CAST(MSDN.Data AS INT) AS 'Data', SUM(CAST(MSDN.Data AS INT)) AS 'Total',
(I think it is right!)
but the outcome is:
Column PupilPersonalDetails.ForeName is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Start from this:
SELECT PPD.PupilID
,PPD.Forename
,PPD.Surname
,SUM(MSDN.Data) 'Total'
FROM CurrentPupil
INNER JOIN PupilPersonalDetails PPD ON PPD.PupilID=CurrentPupil.PupilID
INNER JOIN PupilCurrentSchool PCS ON PCS.PupilID=PPD.PupilID
INNER JOIN SchoolLookupDetails FL ON PCS.Form=FL.LookupDetailsID AND FL.LookupID=1002
INNER JOIN SchoolLookupDetails HL ON PCS.House=HL.LookupDetailsID AND HL.LookupID=1001
INNER JOIN MarksheetDataNumeric MSDN ON MSDN.PupilID=PPD.PupilID
INNER JOIN ColumnsMaster CM ON CM.ColumnID=MSDN.ColumnID AND CM.ColumnTitle LIKE '%week%'
INNER JOIN ClusterMaster CLM ON CLM.ClusterID=SUBSTRING(PPD.SchoolID,0,4)
INNER JOIN ColumnReportingPeriods CRP ON CRP.ColumnID=CM.ColumnID
INNER JOIN ReportingPeriods RP ON RP.AcademicYear=CLM.CurrentAcademicYear AND RP.ReportingPeriodID=CRP.ReportingPeriodID
WHERE ('%wc%'='%wc%')
GROUP BY PPD.PupilID
,PPD.Forename
,PPD.Surname
If you want to have more columns in the result you can add them, but since you are using an aggregation function SUM you have to have all these columns - except the one you are aggregating (summing in this case) - mentioned in the GROUP BY clause.

Related

SQL Self Join to work out freight percentage when invoices are stored in the same table

I need to work out the freight percentage value on each shipment the company brings in. The invoices for the freight and the goods are stored in the same table, VSI denotes a goods invoice, VBL denotes a freight invoice, they are joined together via a job cost. I have tried to self join the sets of tables, but the end sum is always multiplied by the amount of matching records. Any help would be appreciated.
Tables
JobCost
JobCostID JobCostDescription JobCostNumber
4910 ITS-1005104 JBC-1004880
4911 ITS-1005105 JBC-1004881
PurchaseInvoice
PIID PINumber ExchangeRate VendorId
1 VSI-1 1 1
2 VSI-2 1 2
3 VBL-1 1 3
PurchaseInvoiceItem
PIItemID PIID Item
1 1 ProductA
2 1 ProductB
3 2 ProductA
4 2 ProductB
5 3 Fuel
6 3 Handling
PurchaseInvoiceItemDetail
PIItemDetailID QtyShipped Cost PIItemID JobCostID
1 2 2500 1 4910
2 2 2500 2 4910
3 2 2500 3 4911
4 2 2500 4 4911
5 1 25 5 4910
6 1 75 6 4910
Vendor
VendorId VendorCode VendorName
1 VEN1 Vendor1
2 VEN2 Vendor2
3 Freight1 Agent1
Desired result
JobCostID JobCostDescription VendorCode VendorName FreightAgentCode FreightAgentName InvoiceTotal FreightTotal FreightPercentage
4910 ITS-1005104 VEN1 Vendor1 Freight1 Agent1 10000 100 1%
4920 ITS-1005105 VEN2 Vendor2 10000
SELECT tblJobCost1.JobCostID, tblJobCost1.JobCostDescription, tblVendor1.VendorCode, tblVendor1.VendorName, tblVendor2.VendorCode AS 'FreightAgentCode', tblVendor2.VendorName AS 'FreightAgentName',
SUM(PurchaseInvoiceItemDetail1.QtyShipped*PurchaseInvoiceItemDetail1.Cost*PurchaseInvoice1.ExchangeRate) AS 'InvoiceTotal',
SUM(PurchaseInvoiceItemDetail2.QtyShipped*PurchaseInvoiceItemDetail2.Cost*PurchaseInvoice2.ExchangeRate) AS 'FreightTotal',
SUM(PurchaseInvoiceItemDetail2.QtyShipped*PurchaseInvoiceItemDetail2.Cost*PurchaseInvoice2.ExchangeRate)/SUM(PurchaseInvoiceItemDetail1.QtyShipped*PurchaseInvoiceItemDetail1.Cost*PurchaseInvoice1.ExchangeRate)*100 AS 'FreightPercentage'
FROM tblJobCost AS tblJobCost1
LEFT JOIN tblJobCost AS tblJobCost2 ON tblJobCost1.JobCostID = tblJobCost2.JobCostID
LEFT JOIN tblPurchaseInvoiceItemDetail AS tblPurchaseInvoiceItemDetail1 ON tblJobCost1.JobCostID = tblPurchaseInvoiceItemDetail1.JobCostID
LEFT JOIN tblPurchaseInvoiceItemDetail AS tblPurchaseInvoiceItemDetail2 ON tblJobCost2.JobCostID = tblPurchaseInvoiceItemDetail2.JobCostID
LEFT JOIN tblPurchaseInvoiceItem AS tblPurchaseInvoiceItem1 ON tblPurchaseInvoiceItem1.PIItemID = tblPurchaseInvoiceItemDetail1.PIItemID
LEFT JOIN tblPurchaseInvoiceItem AS tblPurchaseInvoiceItem2 ON tblPurchaseInvoiceItem2.PIItemID = tblPurchaseInvoiceItemDetail2.PIItemID
LEFT JOIN tblPurchaseInvoice AS tblPurchaseInvoice1 ON tblPurchaseInvoiceItem1.PIID = tblPurchaseInvoice1.PIID
LEFT JOIN tblPurchaseInvoice AS tblPurchaseInvoice2 ON tblPurchaseInvoiceItem2.PIID = tblPurchaseInvoice2.PIID
LEFT JOIN tblVendor AS tblVendor1 ON tblVendor1.VendorId = tblPurchaseInvoice1.VendorID
LEFT JOIN tblVendor AS tblVendor2 ON tblVendor2.VendorId = tblPurchaseInvoice2.VendorID
WHERE tblPurchaseInvoice1.PINumber LIKE 'VSI%' AND tblPurchaseInvoice2.PINumber LIKE 'VBL%'
GROUP BY tblJobCost1.JobCostID, tblJobCost1.JobCostDescription, tblVendor1.VendorCode, tblVendor1.VendorName, tblVendor2.VendorCode, tblVendor2.VendorName
Then you are missing a critical condition:
...
LEFT JOIN tblPurchaseInvoiceItemDetail AS tblPurchaseInvoiceItemDetail2
ON tblJobCost2.JobCostID = tblPurchaseInvoiceItemDetail2.JobCostID
AND tblPurchaseInvoiceItemDetail1.JobCostID = tblPurchaseInvoiceItemDetail2.JobCostID
...

The DATEDIFF function return 2 row

I have the query that works properly and i get the following output :
9 1116 JOHN 0590056093 9106809105 3 A NULL D
9 1117 SARA 0015562451 9203410410 3 A NULL D
9 1118 DAVID 5560101753 9375115360 3 B NULL D
After adding the datediff column my output is as follows
9 1116 JOHN 0590056093 9106809105 3 A NULL D 10
9 1116 JOHN 0590056093 9106809105 3 A NULL D 1
9 1117 SARA 0015562451 9203410410 3 A NULL D 10
9 1117 SARA 0015562451 9203410410 3 A NULL D 1
9 1118 DAVID 5560101753 9375115360 3 B NULL D 10
9 1118 DAVID 5560101753 9375115360 3 B NULL D 1
What is the reason for displaying the 1 in the datediff column?
Query :
select distinct t1.*, fs.Name+' '+ed.Academic as takhasos, Articles.Title, MT.Name as paye,
datediff(m,Projects.StartDateProject, Projects.EndDateProject) as datedif
from
(select RC.ID, RCU.UserID, u.Name + ' ' + u.Family AS NameFamily, u.UserName, u.Mobile, u.Email, groupED.IdMaghtae
from ResearchersCores AS RC LEFT OUTER JOIN
ResearchersCoreUsers AS RCU ON RC.ID = RCU.ResearchersCoreID LEFT OUTER JOIN
Users AS u ON u.Id = RCU.UserID LEFT OUTER JOIN
(SELECT Eductionals.UserID , Max(Eductionals.MaghtaeID) AS IdMaghtae
FROM Eductionals
GROUP BY Eductionals.UserID) groupED
ON u.Id = groupED.UserID
WHERE (RC.IsEnable = 1) AND (RCU.isEnable = 1) AND (RCU.RoleID = 5) ) t1 left outer join
Eductionals as ED ON ED.UserID = t1.UserID AND t1.IdMaghtae = ed.MaghtaeID left outer join
FieldStudies as FS ON ed.FieldStudy_ID = FS.ID left outer join
Articles ON Articles.UserID = t1.UserID left outer join
Projects ON Projects.RecordID = t1.ID and Projects.ControllerID = 8 left outer join
MaghtaeTahsilis MT On MT.ID = t1.IdMaghtae
where t1.id = 9
I want the following output
9 1116 JOHN 0590056093 9106809105 3 A NULL D 10
9 1117 SARA 0015562451 9203410410 3 A NULL D 10
9 1118 DAVID 5560101753 9375115360 3 B NULL D 10
Your query uses distinct to remove duplicate rows. But the expression that you are adding has different values over these otherwise duplicate rows, so they are now showing in the resultset.
One option would be to use group by instead, and take the max() of datediff. This requires you to repeat all other columns in the select clause in the group by clause as well:
select
t1.col1,
t1.col2,
...,
max(datediff(m,Projects.StartDateProject, Projects.EndDateProject)) as datedif
from ...
where t1.id = 9
group by t1.col1, t1.col2, ...

Using two Count() functions without changing the results

SELECT CARRIER.CARRIERID, PLAN.PLANID, PLNDESCRIPTION,
COUNT(MEMBER.PLANID) AS MBRCNT
FROM CARRIER
LEFT OUTER JOIN PLAN
ON CARRIER.CARRIERID = PLAN.CARRIERID
LEFT OUTER JOIN MEMBER
ON PLAN.PLANID = MEMBER.PLANID
GROUP BY CARRIER.CARRIERID, PLAN.PLANID, PLNDESCRIPTION
ORDER BY CARRIER.CARRIERID;
results in
CARR PLANID PLNDESCRIPTION MBRCNT
---- ---------- ----------------------------------- ----------
ANTH 4 Single SuperMed 6
ANTH 5 2-Party SuperMed 4
ANTH 6 Family SuperMed 7
BCBS 1 Single Basic Medical 9
BCBS 2 2-Party Basic Medical 15
BCBS 3 Family Basic Medical 11
DLT 7 Single Dental Only 6
DLT 8 Family Dental Only 0
MM 10 Single SuperMed with Dental 5
MM 11 2-Party SuperMed with Dental 0
MM 12 Family SuperMed with Dental 2
NWD 9 Life Only 2
PHC 0
and
SELECT CARRIER.CARRIERID, COUNT(PLAN.CARRIERID)
FROM CARRIER
LEFT OUTER JOIN PLAN
ON CARRIER.CARRIERID = PLAN.CARRIERID
LEFT OUTER JOIN MEMBER
ON PLAN.PLANID = MEMBER.PLANID
GROUP BY CARRIER.CARRIERID
ORDER BY CARRIER.CARRIERID;
result in
CARR COUNT(PLAN.CARRIERID)
---- ---------------------------------------
ANTH 17
BCBS 35
DLT 7
MM 8
NWD 2
PHC 0
How can I combine these to get all of the rows next to each other?
I think you just want analytic functions:
SELECT c.CARRIERID, p.PLANID, p.PLNDESCRIPTION,
COUNT(m.PLANID) AS MBRCNT,
SUM(COUNT(m.PLANID)) OVER (PARTITION BY c.CARRIERID) as CNT_2
FROM CARRIER c LEFT JOIN
PLAN p
ON c.CARRIERID = p.CARRIERID LEFT JOIN
MEMBER m
ON p.PLANID = m.PLANID
GROUP BY c.CARRIERID, p.PLANID, p.PLNDESCRIPTION
ORDER BY c.CARRIERID;
One option is to full outer join them together
with firstCount as (
SELECT CARRIER.CARRIERID, PLAN.PLANID, PLNDESCRIPTION,
COUNT(MEMBER.PLANID) AS MBRCNT
FROM CARRIER
LEFT OUTER JOIN PLAN
ON CARRIER.CARRIERID = PLAN.CARRIERID
LEFT OUTER JOIN MEMBER
ON PLAN.PLANID = MEMBER.PLANID
GROUP BY CARRIER.CARRIERID, PLAN.PLANID, PLNDESCRIPTION
ORDER BY CARRIER.CARRIERID
)
secondCount as (
SELECT CARRIER.CARRIERID, COUNT(PLAN.CARRIERID) as count
FROM CARRIER
LEFT OUTER JOIN PLAN
ON CARRIER.CARRIERID = PLAN.CARRIERID
LEFT OUTER JOIN MEMBER
ON PLAN.PLANID = MEMBER.PLANID
GROUP BY CARRIER.CARRIERID
ORDER BY CARRIER.CARRIERID
)
select coalesce(firstCount.carrierId, secondCount.carrierId) as carrierId,
firstCount.PLANID,
firstCount.PLNDESCRIPTION,
firstCount.MBRCNT,
secondCount.Count
from firstCount
full outer join secondCount on firstCount.CarrierId = secondCount.CarrierId

SQL Queue to get workload in 2 weeks [SQL Server]

Currently, the queue shows me the workload of products in a oven and for product which are in the oven too, but actually for some hours in a test outside of the oven.
I count the h with "gesamt" for each product -> this show me how Long they stay already in the oven. Mostly the products stay 1000h in the oven its defined in "Zielgröße" in the db.
What I want is that the queue should show me the workload of the oven for the next 2 weeks as a prediction (336h). Thats all "gesamt" which is over "Zielgröße" (mostly 1000) not shown in the queue maybe handled in a temporary table or whatever.
Is it possible to handle this in Micrososft SQL Server?
Here is the code:
SELECT TesterID,Name, TesterNr, COUNT(Name) as Anzahl, gesamt FROM
(SELECT AllgemeineAngaben.QualiID,
Bezeichnung,
AnzModule,
Tester.Name, TesterNr,
Testname,
v_gesamtBerechnungLaufend.TestaufstellungID,
lastRO,
gesamt,
v_gesamtBerechnungLaufend.Einheit,
v_gesamtBerechnungLaufend.PlanID,
v_gesamtBerechnungLaufend.TesterID
FROM DB.dbo.AllgemeineAngaben inner join
DB.dbo.v_gesamtBerechnungLaufend on
AllgemeineAngaben.QualiID = v_gesamtBerechnungLaufend.QualiID inner join
DB.dbo.Tester on
Tester.TesterID = v_gesamtBerechnungLaufend.TesterID inner join
DB.dbo.Testaufstellung on
Testaufstellung.TestaufstellungID = v_gesamtBerechnungLaufend.TestaufstellungID inner join
DB.dbo.Testnamen on Testnamen.TestnameID = Testaufstellung.TestnameID
Where Tester.Name = 'KPS02'
UNION ALL
SELECT AllgemeineAngaben.QualiID,
Bezeichnung, AnzModule, Tester.Name, TesterNr,
Testname,
Testaufstellung.TestaufstellungID,
v_gesamtBerechnung.gesamt as lastRO,
v_gesamtBerechnung.gesamt,
v_gesamtBerechnung.Einheit,
v_gesamtBerechnung.PlanID,
v_gesamtBerechnung.TesterID
FROM DB.dbo.AllgemeineAngaben inner join
DB.dbo.v_gesamtBerechnung on
AllgemeineAngaben.QualiID = v_gesamtBerechnung.QualiID inner join
DB.dbo.Tester on
Tester.TesterID = v_gesamtBerechnung.TesterID inner join
DB.dbo.Testaufstellung on
Testaufstellung.TestaufstellungID = v_gesamtBerechnung.TestaufstellungID inner join
DB.dbo.Testnamen on Testnamen.TestnameID = Testaufstellung.TestnameID
WHERE Testaufstellung.fertig ='0'
AND Testaufstellung.aktiv ='1'
AND Testaufstellung.Zielgröße > v_gesamtBerechnung.gesamt
AND Tester.Name = 'KPS02'
AND v_gesamtBerechnung.TestaufstellungID not in (Select TestaufstellungID from DB.dbo.v_gesamtBerechnungLaufend)) x
group by TesterID, Name, TesterNr, gesamt
Here the table to show in an example what I want
actual workload
TesterID Name TesterNr Anzahl gesamt
-------------- ------- ---------- ----------- -----------
Product1 8 KPS02 2 1 209
Product2 8 KPS02 2 1 216
Product3 8 KPS02 2 1 816
Product4 8 KPS02 2 1 835
workload in 2 weeks
TesterID Name TesterNr Anzahl gesamt
-------------- ------- ---------- ----------- -----------
Product1 8 KPS02 2 1 545
Product2 8 KPS02 2 1 552
the last recors are over 1000 Zielgröße, so just dont show them in the prediction queue
Product3 8 KPS02 2 1 1152
Product4 8 KPS02 2 1 1171
I hope you guys can follow me. Thanks for your help.
I'll edit this answer until it's solved, but here's my first attempt:
SELECT TesterID,Name, TesterNr, COUNT(Name) as Anzahl, gesamt + 336 as gesamt
FROM
(SELECT AllgemeineAngaben.QualiID,
Bezeichnung,
AnzModule,
Tester.Name, TesterNr,
Testname,
v_gesamtBerechnungLaufend.TestaufstellungID,
lastRO,
gesamt,
v_gesamtBerechnungLaufend.Einheit,
v_gesamtBerechnungLaufend.PlanID,
v_gesamtBerechnungLaufend.TesterID
FROM DB.dbo.AllgemeineAngaben inner join
DB.dbo.v_gesamtBerechnungLaufend on
AllgemeineAngaben.QualiID = v_gesamtBerechnungLaufend.QualiID inner join
DB.dbo.Tester on
Tester.TesterID = v_gesamtBerechnungLaufend.TesterID inner join
DB.dbo.Testaufstellung on
Testaufstellung.TestaufstellungID = v_gesamtBerechnungLaufend.TestaufstellungID inner join
DB.dbo.Testnamen on Testnamen.TestnameID = Testaufstellung.TestnameID
Where Tester.Name = 'KPS02'
UNION ALL
SELECT AllgemeineAngaben.QualiID,
Bezeichnung, AnzModule, Tester.Name, TesterNr,
Testname,
Testaufstellung.TestaufstellungID,
v_gesamtBerechnung.gesamt as lastRO,
v_gesamtBerechnung.gesamt,
v_gesamtBerechnung.Einheit,
v_gesamtBerechnung.PlanID,
v_gesamtBerechnung.TesterID
FROM DB.dbo.AllgemeineAngaben inner join
DB.dbo.v_gesamtBerechnung on
AllgemeineAngaben.QualiID = v_gesamtBerechnung.QualiID inner join
DB.dbo.Tester on
Tester.TesterID = v_gesamtBerechnung.TesterID inner join
DB.dbo.Testaufstellung on
Testaufstellung.TestaufstellungID = v_gesamtBerechnung.TestaufstellungID inner join
DB.dbo.Testnamen on Testnamen.TestnameID = Testaufstellung.TestnameID
WHERE Testaufstellung.fertig ='0'
AND Testaufstellung.aktiv ='1'
AND Testaufstellung.Zielgröße > v_gesamtBerechnung.gesamt
AND Tester.Name = 'KPS02'
AND v_gesamtBerechnung.TestaufstellungID not in (Select TestaufstellungID from DB.dbo.v_gesamtBerechnungLaufend)) x
group by TesterID, Name, TesterNr, gesamt
) A
WHERE gesamt + 336 < 1000
It seems to me like all you need to do is add 336 to the current values and then filter out anything less than 1000.

SQL Sum double counting

My SQL is double counting 'Fund1Amount' and 'Fund2Amount' and 'TotalAllDonations' I have a record where the values of the FundAmount1 should = 10 and FundAmount2 should = 20 but they equal 20 & 40 and the total is double. I am using INNER JOINs twice on the same table abc_donationdetail which i am not sure if this is the problem.
SELECT
C.FirstName, C.LastName,
SUM(D.abc_totalamount) AS TotalAllDonations,
SUM(CASE WHEN DBU.abc_fundidname = 'Fund1' THEN DBU.abc_amount END) AS Fund1Amount,
SUM(CASE WHEN DBE.abc_fundidname = 'Fund2' THEN DBE.abc_amount END) AS Fund2Amount
FROM
Contact C
INNER JOIN
Account A ON C.parentcustomerid = A.accountid
INNER JOIN
Account PA ON A.parentaccountid = PA.accountid
INNER JOIN
abc_donation D ON D.abc_person = C.contactid
LEFT JOIN
abc_donationdetail DBU ON DBU.abc_donationid = D.abc_donationid
AND DBU.abc_fundidname= 'Fund1'
LEFT JOIN
abc_donationdetail DBE ON DBE.abc_donationid = D.abc_donationid
AND DBE.abc_fundidname = 'Fund2'
LEFT JOIN
abc_mmcs GD ON GD.abc_donor = C.contactid
LEFT JOIN
sab_item LIBU ON LIBU.sab_itemid = GD.abc_companyid
AND LIBU.sab_name = 'Fund1'
LEFT JOIN
sab_item LIBE ON LIBE.sab_itemid = GD.abc_companyid
AND LIBE.sab_name = 'Fund2'
where C.StateCode = 0 AND (GD.abc_enddate > GETDATE() or GD.abc_enddate IS NULL)
group by C.abc_memberid, C.FirstName, C.LastName , C.StateCode, A.name, A.parentaccountidname, A.dd_number, PA.dd_number, C.parentcustomeridname
order by C.lastname
Current
FN LN Total Fund1 Fund2
James Brown 70 40 30
Phillip Smith 160 60 100
Peter Jones 80 40 40
Vincent Limp 48 48 NULL
Michael Collins 60 60 NULL
Desired
FN LN Total Fund1 Fund2
James Brown 35 20 15
Phillip Smith 80 30 50
Peter Jones 40 20 20
Vincent Limp 24 24 NULL
Michael Collins 30 30 NULL
Any help would be great.
Thanks
If the problem is only in duplicates, than simply make a subquery:
Select fld, sum(value)
from (select distinct fld, value from tbl) as a
I can't say much here as there are lots of tables joined here and I don't know their schema. At most, I can suggest you to add group by with person's id and fund id as it'll remove the duplicates.
SELECT
C.FirstName, C.LastName,
SUM(D.abc_totalamount) AS TotalAllDonations,
SUM(CASE WHEN DBU.abc_fundidname = 'Fund1' THEN DBU.abc_amount END) AS Fund1Amount,
SUM(CASE WHEN DBU.abc_fundidname = 'Fund2' THEN DBU.abc_amount END) AS Fund2Amount
FROM
Contact C
INNER JOIN
Account A ON C.parentcustomerid = A.accountid
INNER JOIN
Account PA ON A.parentaccountid = PA.accountid
INNER JOIN
abc_donation D ON D.abc_person = C.contactid
LEFT JOIN
abc_donationdetail DBU ON DBU.abc_donationid = D.abc_donationid
AND (DBU.abc_fundidname= 'Fund1'
OR DBU.abc_fundidname = 'Fund2') //MERGED 2 JOINS
LEFT JOIN
abc_mmcs GD ON GD.abc_donor = C.contactid
LEFT JOIN
sab_item LIBU ON LIBU.sab_itemid = GD.abc_companyid
AND LIBU.sab_name = 'Fund1'
LEFT JOIN
sab_item LIBE ON LIBE.sab_itemid = GD.abc_companyid
AND LIBE.sab_name = 'Fund2'
where C.StateCode = 0 AND (GD.abc_enddate > GETDATE() or GD.abc_enddate IS NULL)
group by C.abc_memberid, C.FirstName, C.LastName , C.StateCode, A.name, A.parentaccountidname, A.dd_number, PA.dd_number, C.parentcustomeridname order by C.lastname
Hope it works!