CASE statement returning duplicate rows. I only want 1 row per record - sql-server-2012

The following CASE statement is returning 2 rows, 1 with the joindate = to the join date (cd.user_d1) if the person is a member and null if there is no join date on the record. How can i get the CASE statement to only return 1 row with the joindate field either null or with the member's join date?
I've searched and found solutions for other type fields with SUM, but nothing for date fields. Any help would be greatly appreciated.
SELECT DISTINCT
c.master_customer_id ,
c.SUB_CUSTOMER_ID ,
c.PRIMARY_EMAIL_ADDRESS ,
c.FIRST_NAME ,
c.INFORMAL_SALUTATION ,
c.LAST_NAME ,
c.LABEL_NAME ,
c.PRIMARY_JOB_TITLE ,
cad.company_name ,
ca.ADDRESS_1 ,
ca.ADDRESS_2 ,
ca.ADDRESS_3 ,
ca.ADDRESS_4 ,
ca.CITY ,
ca.STATE ,
ca.POSTAL_CODE ,
ca.COUNTRY_DESCR ,
c.PRIMARY_URL ,
c.BIRTH_DATE ,
CASE WHEN cd.DEMOGRAPHIC_SUBCODE = 'join_date'
AND cd.user_d1 IS NOT NULL THEN cd.USER_D1
ELSE NULL
END AS JOINDATE ,
CASE WHEN cc.comm_type_code = 'EMAIL'
AND cc.primary_flag <> 'Y' THEN cc.formatted_phone_address
END AS secondary_email
FROM customer c
LEFT OUTER JOIN CUS_DEMOGRAPHIC cd ON cd.MASTER_CUSTOMER_ID = c.MASTER_CUSTOMER_ID
LEFT OUTER JOIN CUS_ADDRESS ca ON ca.MASTER_CUSTOMER_ID = c.MASTER_CUSTOMER_ID
LEFT OUTER JOIN CUS_ADDRESS_DETAIL cad ON cad.CUS_ADDRESS_ID = ca.CUS_ADDRESS_ID
LEFT OUTER JOIN CUS_COMMUNICATION cc ON cc.MASTER_CUSTOMER_ID = c.MASTER_CUSTOMER_ID
WHERE c.CUSTOMER_STATUS_CODE = 'active'
AND c.ALLOW_EMAIL_FLAG = 'Y'
AND cad.PRIORITY_SEQ = 0
AND c.PRIMARY_EMAIL_ADDRESS <> ' '
ORDER BY c.MASTER_CUSTOMER_ID

Related

Use CTE in SQL to flag DUPLICATES and reference in sub-query

So I have the following CTE:
with dupeinv AS (
select * from (
select
tci.t_idoc,
tci.t_idat,
ROW_NUMBER() OVER (partition by tci.t_idoc ORDER BY tci.t_idoc, tci.t_idat DESC) as rn
from [ln106].[dbo].tcisli305100 tci
) as t
where t.rn = 1
)
There are duplicates in the above table ([ln106].[dbo].tcisli305100) , hence the CTE to get single values. I want to format just these values in the below query (prefixed with ---)
select 'JCI' as BU,
RTRIM(LTRIM(cl.t_orno)) AS SALES_ORDER_NUMBER
, cl.t_pono AS SALES_ORDER_LINE_NUMBER
, CONCAT(cl.t_shpm, cl.t_pono, cl.t_idoc) AS SHIPPING_RECORD_ID
,CASE WHEN cl.t_dqua = 0 or cl.t_dqua is null THEN cl.t_amti ELSE
cl.t_amti / cl.t_dqua END AS AR_INVOICE_LINE_ITEM_PRICE_LOCAL
, cl.t_line AS AR_INVOICE_LINE_NUMBER
, cl.t_dqua AS AR_INVOICE_LINE_ITEM_QUANTITY
--- , concat(dupeinv.t_idoc,'|',format(dupeinv.t_idat,'MMddyyyy') ---
,ci.t_ccur AS AR_INVOICE_CURRENCY
, ci.t_idat AS AR_INVOICE_DATE
FROM [ln106].[dbo].tcisli310100 cl
LEFT JOIN [ln106].[dbo].tcisli305100 ci ON cl.t_idoc = ci.t_idoc
LEFT JOIN t di on cl.t_doc = di_t_doc
LEFT JOIN (SELECT t_orno,t_pono FROM [ln106].[dbo].ttdsls401100 WHERE t_oltp <> 1 group by t_orno,t_pono) as l --Jed 10162020 Changed the join to prevent duplicate records
ON l.t_orno=cl.t_orno COLLATE SQL_Latin1_General_CP1_CI_AS AND l.t_pono=cl.t_pono
LEFT JOIN dupeinv tci on cl.r_idoc = ci.t_doc
WHERE ci.t_idat > '2017'
Query doesn't like me referencing it in the main query. Can anyone help, or suggest a better idea?
Your final query should look something like this:
WITH dupeinv AS
(SELECT *
FROM
(SELECT tci.t_idoc,
tci.t_idat,
ROW_NUMBER() OVER (PARTITION BY tci.t_idoc
ORDER BY tci.t_idoc,
tci.t_idat DESC) AS rn
FROM [ln106].[dbo].tcisli305100 tci) AS t
WHERE t.rn = 1 )
SELECT 'JCI' AS BU,
RTRIM(LTRIM(cl.t_orno)) AS SALES_ORDER_NUMBER ,
cl.t_pono AS SALES_ORDER_LINE_NUMBER ,
CONCAT(cl.t_shpm, cl.t_pono, cl.t_idoc) AS SHIPPING_RECORD_ID ,
CASE
WHEN cl.t_dqua = 0
OR cl.t_dqua IS NULL THEN cl.t_amti
ELSE cl.t_amti / cl.t_dqua
END AS AR_INVOICE_LINE_ITEM_PRICE_LOCAL ,
cl.t_line AS AR_INVOICE_LINE_NUMBER ,
cl.t_dqua AS AR_INVOICE_LINE_ITEM_QUANTITY ,
concat(dupeinv.t_idoc,
'|',
format(dupeinv.t_idat, 'MMddyyyy')) ,
ci.t_ccur AS AR_INVOICE_CURRENCY ,
ci.t_idat AS AR_INVOICE_DATE
FROM [ln106].[dbo].tcisli310100 cl
LEFT JOIN [ln106].[dbo].tcisli305100 ci ON cl.t_idoc = ci.t_idoc
LEFT JOIN t di ON cl.t_doc = di_t_doc
LEFT JOIN
(SELECT t_orno,
t_pono
FROM [ln106].[dbo].ttdsls401100
WHERE t_oltp <> 1
GROUP BY t_orno,
t_pono) AS l --Jed 10162020 Changed the join to prevent duplicate records
ON l.t_orno=cl.t_orno COLLATE SQL_Latin1_General_CP1_CI_AS
AND l.t_pono=cl.t_pono
LEFT JOIN dupeinv tci ON cl.r_idoc = ci.t_doc
WHERE ci.t_idat > '2017'

Left outer join multiple selects

I have the following sql statement, that does exactly what it should:
select C.Company_RecID, C.Contact_RecID, C.First_Name, C.Last_Name,
C.Title, C.Inactive_Flag, e.Description
FROM dbo.Contact AS C
LEFT OUTER JOIN dbo.Contact_Communication AS e ON C.Contact_RecID = e.Contact_RecID
AND e.Communication_Type_RecID = 1 AND e.Default_Flag = 1
However, in dbo.contact_communication, the description field means different things depending upon the communication_type_recID. If it's 1, description is an email address. If it's 4, it's a cell phone number, if it's 2, it's a direct number, and if it's 14, it's a personal cell phone number.
I'd like to change the query to return three additional columns. Column 8 would be the value of description if there is a record for this contact with a recid of 4, column 9 the value of description if there is a record for this contact with a recid of 2, and column 10 if there is a value of 14.
Something like this should be pretty close as I understand what you are looking for.
select C.Company_RecID
, C.Contact_RecID
, C.First_Name
, C.Last_Name
, C.Title
, C.Inactive_Flag
, e.Description
, EmailAddress = MAX(case when communication_type_recID = 1 then e.Description end)
, CellPhone = MAX(case when communication_type_recID = 4 then e.Description end)
, DirectNumber = MAX(case when communication_type_recID = 2 then e.Description end)
, PersonalCellPhone = MAX(case when communication_type_recID = 14 then e.Description end)
FROM dbo.Contact AS C
LEFT OUTER JOIN dbo.Contact_Communication AS e ON C.Contact_RecID = e.Contact_RecID
AND e.Communication_Type_RecID IN (1,2,4,14)
AND e.Default_Flag = 1
group by C.Company_RecID
, C.Contact_RecID
, C.First_Name
, C.Last_Name
, C.Title
, C.Inactive_Flag
, e.Description
I think UNION might help you. (https://learn.microsoft.com/en-us/sql/t-sql/language-elements/set-operators-union-transact-sql?view=sql-server-2017)
You can try something like this:
select col_1, 'something' as A, '' as B from TableA
union
select col_2, '' as A, 'something' as B from TableA
col_1 and col_2 are actual columns in the table, while A and B are aliases for this extra information.
Without aggregation
select C.Company_RecID
, C.Contact_RecID
, C.First_Name
, C.Last_Name
, C.Title
, C.Inactive_Flag
, e.Description
, e1.Description as EmailAddress
, e2.Description as CellPhone
, e4.Description as DirectNumber
, e14.Description as PersonalCellPhone
FROM dbo.Contact AS C
LEFT OUTER JOIN dbo.Contact_Communication AS e1
ON e1.Contact_RecID = C.Contact_RecID
AND e1.Communication_Type_RecID = 1
AND e1.Default_Flag = 1
LEFT OUTER JOIN dbo.Contact_Communication AS e2
ON e2.Contact_RecID = C.Contact_RecID
AND e2.Communication_Type_RecID = 2
AND e2.Default_Flag = 1
LEFT OUTER JOIN dbo.Contact_Communication AS e4
ON e4.Contact_RecID = C.Contact_RecID
AND e4.Communication_Type_RecID = 4
AND e4.Default_Flag = 1
LEFT OUTER JOIN dbo.Contact_Communication AS e14
ON e14.Contact_RecID = C.Contact_RecID
AND e14.Communication_Type_RecID = 14
AND e14.Default_Flag = 1

How to add Parameter to report

select distinct sotr_sys_no
, SODETS_VINYL_COLOUR
, SODETS_MDF_COLOUR
, SOTR_PROMISED_DATE
, DATEDIFF(dd,getdate(),sotr_promised_date) as DueDays
, AEXTRA_5_SHORT_NAME
, AEXTRA_5_VINYL_PARTCODE
, CASE WHEN SODETS_MDF_COLOUR > '0' THEN AltMDFCode ELSE AEXTRA_5_MDF_PARTCODE END AS AEXTRA_5_MDF_PARTCODE
, ISNULL(Vinylqty,0) As VinylQty
, ISNULL(MDFqty,0) as MDFQty
, Vinyldue
, MDFdue
, WO.WOOutstanding
from Defactouser.F_SO_Transaction WITH (NOLOCK)
inner join defactouser.F_SO_Transaction_Details WITH (NOLOCK)
on sotr_sys_no = sotd_head_no
inner join defactouser.F_SO_Transaction_Details_Extra WITH (NOLOCK)
on SOTD_SYS_NO = SODETS_LINK
left outer join (
select distinct AEXTRA_5_CODE as AltMDFKey
, AEXTRA_5_MDF_PARTCODE AS AltMDFCode
from DeFactoUser.F_AD_Extra_5 WITH (NOLOCK)
) as AltMDF
on SODETS_MDF_COLOUR = AltMDF.AltMDFKey
left outer join defactouser.F_AD_Extra_5 WITH (NOLOCK)
on SODETS_VINYL_COLOUR = [AEXTRA_5_CODE]
inner join defactouser.F_ST_Products WITH (NOLOCK)
on sotd_strc_code = strc_code
left Outer join (
SELECT Product_Code As VinylStockCode, sum(Physical_Qty_Units) as Vinylqty FROM DBO.DFBI_Stock_Physical WITH (NOLOCK)
WHERE Warehouse = 'DOORS' and LEFT(product_code ,3) = 'vfl'
Group By Product_Code
HAVING SUM(Physical_Qty_Units) >0
) VinylStock
on AEXTRA_5_VINYL_PARTCODE = VinylStock.VinylStockCode
left outer join (
SELECT Product_Code As MDFStockCode, sum(Physical_Qty_Units) as MDFqty FROM DBO.DFBI_Stock_Physical WITH (NOLOCK)
WHERE Warehouse = 'PANELS' and LEFT(product_code ,3) = 'MDF'
Group By Product_Code
HAVING SUM(Physical_Qty_Units) >0
) MDFStock
on CASE WHEN SODETS_MDF_COLOUR > '0' THEN AltMDF.AltMDFCode ELSE AEXTRA_5_MDF_PARTCODE END = MDFStock.MDFStockCode
left Outer JOin (select stex_strc_code as VinylStex , sum(STEX_QTY_UNITS) as Qty, MIN(stex_promised_date) as Vinyldue
from defactouser.F_ST_Transaction_Expediting
where left(stex_strc_code ,3) = 'vfl'
and stex_type = 'pop+'
group By STEX_STRC_CODE
) VinylStockIn
on AEXTRA_5_VINYL_PARTCODE = VinylStex
left Outer Join (
select stex_strc_code as MDFStex , sum(STEX_QTY_UNITS) as Qty, MIN(stex_promised_date) as MDFdue
from defactouser.F_ST_Transaction_Expediting
where left(stex_strc_code ,3) = 'mdf'
and stex_type = 'pop+'
group By STEX_STRC_CODE
) MDFStockIn on CASE WHEN SODETS_MDF_COLOUR > '0' THEN AltMDF.AltMDFCode ELSE AEXTRA_5_MDF_PARTCODE END = MDFStex
LEFT OUTER JOIN (
select SOTD_HEAD_NO, SODETS_VINYL_COLOUR as WOVinyl, SUM(BMTD_QTY_OUTSTANDING) as WOOutstanding from defactouser.f_bm_transactions_details
inner join defactouser.F_SO_Transaction_Details on BMTD_ORDER_LINK_NUMBER = SOTD_SYS_NO
inner join defactouser.F_SO_Transaction_Details_Extra on BMTD_ORDER_LINK_NUMBER = SODETS_LINK
where bmtd_type = 1 and bmtd_bmtr_type = 0 and bmtd_stwh_code in ('doors', 'shef trans') and SOTD_STATUS <99
Group by SOTD_HEAD_NO, SODETS_VINYL_COLOUR
) WO
on sotr_sys_no = WO.SOTD_HEAD_NO AND SODETS_VINYL_COLOUR = WO.WOVinyl
where (SOTD_QTY_UNITS_OUTSTANDING > 0
and SOTR_TYPE = 10
and SOTD_STWH_CODE IN ('doors' , 'hpp shef')
and left(sotd_strc_code ,5) <> 'drill'
and SOTR_CUST_CODE <>'hpp'
and STRC_ANAL1 = '1027'
and ISNULL(VinylQty,0) <10
and DATEDIFF(dd,getdate(),sotr_promised_date) <5
)
or
(SOTD_QTY_UNITS_OUTSTANDING > 0
and SOTR_TYPE = 10
and SOTD_STWH_CODE IN ('doors' , 'hpp shef')
and left(sotd_strc_code ,5) <> 'drill'
and SOTR_CUST_CODE <>'hpp'
and STRC_ANAL1 = '1027'
and ISNULL(MDFQty,0) <4
and DATEDIFF(dd,getdate(),sotr_promised_date) <5
)
Order By MDFQty, AEXTRA_5_MDF_PARTCODE
Currently this query produces a report that returns a table with products due to arrive in the next 5 days. How do I add a parameter to the report that will show me the results as it is, and then also to show a report for products due in whenever. I am using Report Builder 3.0, and have tried to add a parameter but cannot get the desired result.
Can this be done without editing the query and just in report builder?
Change you WHERE clause and replace < 5 with < #Days. Assuming the query is not a stored proc and is directly in the dataset query then SSRS will automatically add the #Days parameter to your report.

Oracle Join - Which is faster - using the whole table or a subquery that has specific columns needed in the table?

I am really new into optimizing queries. Could you please advise which INNER JOIN runs faster?
Please note that i am using two different ways of inner join syntax(have same # of records)
1.) INNER JOIN of subqueries that have DISTINCT and selected columns only from its respective table
select
fac.fac_id ,
dept.dept_id ,
wk.week_id ,
sum(case when TRIM(fpl.MEASURE) like '%Salar%Wage%' then DATAVALUE else 0 end) WAGES_AMT,
sum(case when TRIM(fpl.MEASURE) like '%Tot%Man%hour%Ret%' then DATAVALUE else 0 end) MANHRS_QTY,
fpl.md_cycle_nbr ,
fpl.md_load_dt
from
EAS_STG.FPA_PLAN_LABOR fpl
INNER JOIN
(
select distinct(dept_nbr), dept_id
from department_D
where regexp_instr( Dept_nbr,'([^0-9])') = 0
) dept
ON TO_NUMBER(TRIM( 'D' FROM fpl.department)) = TO_NUMBER(dept.dept_nbr)
INNER JOIN
(
select distinct(FAC.FAC_NBR), fai.fac_id
from FACILITY_D fac, FACILITY_ALTERNATE_ID fai
where fac.fac_id = fai.fac_id
and fac.company_id = 1101
) fac
ON TRIM(REPLACE(fpl.facility, 'Fac-')) = fac.fac_nbr
INNER JOIN
(
select distinct(wk_hierarchy_id) week_id from DAY_HIERARCHY_D
) wk ON TO_NUMBER(TRIM(REPLACE(fpl.scenario, 'Plan ')) || TRIM(REPLACE(fpl.time, 'Wk '))) = WK.week_id
GROUP BY
fac.fac_id ,
dept.dept_id ,
wk.week_id ,
fpl.md_cycle_nbr ,
fpl.md_load_dt
;
2.) INNER JOIN of the whole table without the selected columns
SELECT fac.fac_id
, dept.dept_id
, d.wk_hierarchy_id week_id
, SUM(CASE WHEN TRIM(fpl.MEASURE) LIKE '%Salar%Wage%' THEN datavalue ELSE 0 END) WAGES_AMT
, SUM(CASE WHEN TRIM(fpl.MEASURE) LIKE '%Tot%Man%hour%Ret%' THEN datavalue ELSE 0 END) MANHRS_QTY
, fpl.md_cycle_nbr
, fpl.md_load_dt
FROM EAS_STG.FPA_PLAN_LABOR fpl
JOIN department_d dept
ON TO_NUMBER(TRIM( 'D' FROM fpl.department)) = TO_NUMBER(dept.dept_nbr)
JOIN facility_d fac
ON TRIM(REPLACE(fpl.facility, 'Fac-')) = fac.fac_nbr
JOIN facility_alternate_id fai
ON fac.fac_id = fai.fac_id
JOIN day_hierarchy_d d
ON TO_NUMBER(TRIM(REPLACE(fpl.scenario, 'Plan ')) || TRIM(REPLACE(fpl.time, 'Wk '))) = d.wk_hierarchy_id
WHERE fac.company_id = 1101
AND REGEXP_INSTR(dept_nbr,'([^0-9])') = 0
GROUP BY fac.fac_id
, dept.dept_id
, d.wk_hierarchy_id
, fpl.md_cycle_nbr
, fpl.md_load_dt
;

sql sum() causing doubling of values with left outer join

The left out join on dbo.SalespersonProject is causing the value for TranAmt to double. I need to sum the legit TranAmt for projects, but adding in the left outer join and SalesPerson02, causes a match an incorrect doubling.
SELECT ARDoc.SlsperId AR_Doc_Sls_ID
, CASE
WHEN ARTran.TranType = 'CM' THEN SUM(ARTran.TranAmt) * -1
ELSE SUM(ARTran.TranAmt)
END TranAmt
, MAX(CASE
WHEN SalesCommOrder = 1 THEN SalesPersonId
END) Salesperson01
, MAX(ISNULL(CASE
WHEN SalesCommOrder = 1 THEN Percentage
END, .03)) Commission01
, MAX(CASE
WHEN SalesCommOrder = 2 THEN SalesPersonId
END) Salesperson02
, MAX(CASE
WHEN SalesCommOrder = 2 THEN Percentage
END) Commission02
, PJPROJ.project PJ_ID
, PJPROJ.project_desc PJ_Description
, PJPROJ.slsperid SME
, ARDoc.CustId Cust_ID
, CASE
WHEN RTRIM(ARTran.InvtId) = 'GRAPHICS' THEN 1
WHEN RTRIM(ARTran.InvtID) = 'SERVICE CONTRACT' THEN 2
END InvtID
, RTRIM(ARDoc.CustId) + ' ' + Customer.BillName Cust_ID_Name
, CONVERT( DATE, ARTran.TranDate, 101) Doc_Date
, ARTran.TranType Doc_Type
, ARTran.RefNbr
, PJPROJ.start_date
, SUM(ARTran.ExtCost) ExtCost
, SUM(ARTran.UnitPrice) UnitPrice
, SUM(ARTran.Qty) Qty
, (
SELECT SUM(b.eac_amount) [Budg Rev]
FROM pjptdsum b
INNER JOIN pjacct a ON a.acct = b.acct
AND a.acct_type = 'RV'
WHERE ARDoc.ProjectID = b.project) Budget_Rev
, (
SELECT SUM(b.eac_amount) [Budg Rev]
FROM pjptdsum b
INNER JOIN pjacct a ON a.acct = b.acct
AND a.acct_type = 'EX'
WHERE ARDoc.ProjectID = b.project) Budget_EAC
, so.TotMerch SalesOrderTotal
, Salesperson.Name
, ARTran.PerPost
, PJPROJ.manager2
, PJEMPLOY.emp_name
FROM Testnewgroundapp.dbo.ARDoc ARDoc
INNER JOIN Testnewgroundapp.dbo.ARTran ARTran ON ARDoc.CustId = ARTran.CustId
AND ARDoc.RefNbr = ARTran.RefNbr
AND ARDoc.DocType = ARTran.TranType
INNER JOIN Testnewgroundapp.dbo.Customer Customer ON ARDoc.CustId = Customer.CustId --INNER JOIN #CustomerTab ct
LEFT OUTER JOIN Testnewgroundapp.dbo.Salesperson Salesperson ON ARDoc.SlsperId = Salesperson.SlsperId
LEFT OUTER JOIN Testnewgroundapp.dbo.PJPROJ PJPROJ ON ARDoc.ProjectID = PJPROJ.project
LEFT OUTER JOIN Testnewgroundapp.dbo.PJEMPLOY PJEMPLOY ON PJPROJ.manager2 = PJEMPLOY.employee
LEFT OUTER JOIN (
SELECT h.PerPost
, h.SlsperID
, SUM(h.TotMerch) TotMerch
FROM SOShipHeader H
GROUP BY h.PerPost
, h.SlsperID) so ON ARTran.PerPost = so.PerPost
AND ARDoc.SlsperId = so.SlsperID
LEFT OUTER JOIN TestCommissions.dbo.SalespersonProject SalespersonProject ON SalespersonProject.ProjectId = PJPROJ.project --AND SalespersonProject.SalesPerson_Id = #ApplicationUserID
LEFT OUTER JOIN TestCommissions.dbo.SalesPerson AppSalesPerson ON AppSalesPerson.Id = SalespersonProject.SalesPerson_Id
WHERE
(ARTran.TranType = 'CM'
AND ARTran.DrCr = 'D'
OR ARTran.DrCr = 'C'
AND
(ARTran.TranType = 'CS'
OR ARTran.TranType = 'DM'
OR ARTran.TranType = 'IN'
)
)
AND ARTran.TaskID NOT LIKE '%60850'
AND ARTRan.TaskID NOT LIKE '%60900'
AND ARTran.invtid <> 'TSCINC001'
AND ARTran.TranClass NOT IN ('F', 'N', 'T')
AND ARTran.Acct NOT IN ('2590', '2040', '2037')
AND CONVERT(INT, ARTran.Acct) > 1301
AND CONVERT(INT, ARTran.PerPost) BETWEEN 201504 AND 201504
AND ARTran.Rlsed = 1
AND PJPROJ.project IS NOT NULL
AND artran.cpnyid IN ('R', 'A')
GROUP BY ARDoc.SlsperId
, ARDoc.ProjectID
, PJPROJ.project
, PJPROJ.project_desc
, PJPROJ.slsperid
, ARDoc.CustId
, ARTran.InvtId
, Customer.BillName
, ARTran.TranDate
, ARTran.TranType
, ARTran.RefNbr
, PJPROJ.start_date
, so.TotMerch
, Salesperson.Name
, ARTran.PerPost
, ARDoc.CpnyID
, PJPROJ.manager2
, PJEMPLOY.emp_name
HAVING ARDoc.SlsperId = 'bpettit'
ORDER BY ARDoc.SlsperId, ARTran.PerPost, PJPROJ.project
If an extra joined table has two records per one main record, this makes each main record appear twice in the result set. The following grouping and summing will then sum each value of the main record or another joined table twice.
Temporarily remove the grouping and summing, but keep all the joins and look at the result set. You will then probably see what causes this doubling.