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

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.

Related

How to get biggest value from 2 or more fields in a subquery

I have a table with customers that I join with a fact table with sales, based on invoices.
What I need from my report is to get in first part the biggest value of sales based on the incoming order type (1,2,3,C,D) for a customer for last year. And in the second part to get the same but for current year. What I get as result from my current query is all incoming order types with the customer revenue made for each of them. I tried with outer apply as subquery to get only the top 1 value ordered by revenue descending, but in the result I get the same - For all order types the customer revenue. Please help! I hope my explanation isn't understood only by me (happens a lot..)
use dwh01;
WITH OrderTypeUsedLY AS
(
SELECT
c.CustomerKey
,c.BranchId
,c.CustomerId
,c.CustomerName
,ISNULL(SUM(y.[Sale_Revenue]), 0) as [Sale_Revenue_LY]
,ISNULL(SUM(y.[Sale_GrossMarginTotal]), 0) as [Sale_GrossMarginTotal_LY]
,y.IncomingOrderTypeId as IncomingOrderType_LY
FROM live.DimCustomer c
left join (SELECT s.CustomerKey,iot.IncomingOrderTypeid, s.[Sale_Revenue], s.[Sale_GrossMarginTotal] FROM [dwh01].[live].[FactSales] s
inner join live.DimDate d
on d.DateId = s.PostingDateKey
inner join live.DimIncomingOrderType iot on iot.IncomingOrderTypeKey = s.IncomingOrderTypeKey
where s.ReportCurrencyId = 'LC'
and D.Year = YEAR(GETDATE())-1 --- Last Year
) y on c.CustomerKey = y.CustomerKey
where c.CustomerKey = '157053'
group by c.CustomerKey, c.CustomerId, c.CustomerName, c.BranchId, y.IncomingOrderTypeId
),
--*********************************************************************************************************************************--
OrderTypeCY as(
SELECT
c.CustomerKey
,c.BranchId
,c.SalesRepKey
,c.CustomerId
,c.CustomerName
,ISNULL(SUM(y.[Sale_Revenue]), 0) as [Sale_Revenue_CY]
,ISNULL(SUM(y.[Sale_GrossMarginTotal]), 0) as [Sale_GrossMarginTotal_CY]
,y.IncomingOrderTypeId as IncomingOrderType_CY
FROM live.DimCustomer c
left join (SELECT s.CustomerKey,iot.IncomingOrderTypeid, s.[Sale_Revenue], s.[Sale_GrossMarginTotal] FROM [dwh01].[live].[FactSales] s
inner join live.DimDate d
on d.DateId = s.PostingDateKey
inner join live.DimIncomingOrderType iot on iot.IncomingOrderTypeKey = s.IncomingOrderTypeKey
where s.ReportCurrencyId = 'LC'
and D.Year = YEAR(GETDATE()) --- Current Year
) y on c.CustomerKey = y.CustomerKey
where c.CustomerKey = '157053'
group by c.CustomerKey, c.CustomerId, c.CustomerName, c.BranchId, y.IncomingOrderTypeId, c.SalesRepKey
)
--*********************************************************************************************************************************--
SELECT
otly.BranchId,
rep.SalesRepId,
rep.SalesRepName,
otly.CustomerId,
otly.CustomerName,
otly.Sale_Revenue_LY,
otly.Sale_GrossMarginTotal_LY,
IncomingOrderType_LY,
otcy.Sale_Revenue_CY,
otcy.Sale_GrossMarginTotal_CY,
IncomingOrderType_CY
from OrderTypeUsedLY otly
left join OrderTypeCY otcy
on otly.CustomerKey = otcy.CustomerKey
join live.DimCustomer cus on cus.CustomerKey = otcy.CustomerKey
join live.DimSalesRep rep on rep.SalesRepKey = otcy.SalesRepKey
order by otcy.Sale_Revenue_CY desc, otly.Sale_Revenue_LY desc
,rep.SalesRepId
And here is the outer apply I tried:
outer apply (
SELECT top 1
iot.IncomingOrderTypeId,
Sale_Revenue
FROM [dwh01].[live].DimIncomingOrderType iot
where iot.IncomingOrderTypeKey = y.IncomingOrderTypeKey
order by Sale_Revenue desc) x
In the first select ( with OrderTypeUsed_LY ) I get this:
And I get the same in the second select, but with the values for current year.
The purpose of the report is to see the difference in the incoming order type most used (most profit made with it) for a customer last year and to see if he continues to use it this year, or uses another incoming order type this year.
Again I'm sorry for the bad explanation, I'm trying my best (I understand myself very well)
Here is the expected result:
Expected Result
I marked in red the last year part and in green the current year part.
If you change the subquery to:
SELECT
iot.IncomingOrderTypeKey,
MAX(Sale_Revenue)
FROM [dwh01].[live].DimIncomingOrderType iot
GROUP BY iot.IncomingOrderTypeKey
then you can JOIN (not APPLY) directly on IncomingOrderTypeKey AND Sale_Revenue.
Try this:
USE dwh01;
DECLARE #CustomerKey varchar(6) = '157053'
, #ReportCurrencyId varchar(2) = 'LC'
, #CurrentYear int = YEAR(GETDATE())
, #TargetYear int = YEAR(GETDATE())-1
;
WITH FactsTable AS
(
SELECT
s.CustomerKey
, i.IncomingOrderTypeid
, [Sale_Revenue] = ISNULL(s.[Sale_Revenue] , 0)
, [Sale_GrossMarginTotal] = ISNULL(s.[Sale_GrossMarginTotal], 0)
, d.[Year]
FROM [dwh01].[live].[FactSales] s
inner join live.DimDate d on d.DateId = s.PostingDateKey
inner join live.DimIncomingOrderType i on i.IncomingOrderTypeKey = s.IncomingOrderTypeKey
where
s.CustomerKey = #CustomerKey
and s.ReportCurrencyId = #ReportCurrencyId
)
, OrderTypeTable
(
SELECT
c.CustomerKey
, c.BranchId
, c.CustomerId
, c.CustomerName
, c.SalesRepKey
, IncomingOrderType_LY = SUM(CASE WHEN y.[Year] = #TargetYear THEN y.IncomingOrderTypeId ELSE 0 END)
, [Sale_Revenue_LY] = SUM(CASE WHEN y.[Year] = #TargetYear THEN y.[Sale_Revenue] ELSE 0 END)
, [Sale_GrossMarginTotal_LY] = SUM(CASE WHEN y.[Year] = #TargetYear THEN y.[Sale_GrossMarginTotal] ELSE 0 END)
, IncomingOrderType_LY = SUM(CASE WHEN y.[Year] = #CurrentYear THEN y.IncomingOrderTypeId ELSE 0 END)
, [Sale_Revenue_CY] = SUM(CASE WHEN y.[Year] = #CurrentYear THEN y.[Sale_Revenue] ELSE 0 END)
, [Sale_GrossMarginTotal_CY] = SUM(CASE WHEN y.[Year] = #CurrentYear THEN y.[Sale_GrossMarginTotal] ELSE 0 END)
FROM live.DimCustomer c
left join FactsTable y on y.CustomerKey = c.CustomerKey
group by
c.CustomerKey
, c.BranchId
, c.CustomerId
, c.CustomerName
, y.IncomingOrderTypeId
, c.SalesRepKey
)
SELECT
O.BranchId
, R.SalesRepId
, R.SalesRepName
, O.CustomerId
, O.CustomerName
, O.Sale_Revenue_LY
, O.Sale_GrossMarginTotal_LY
, O.IncomingOrderType_LY
, O.Sale_Revenue_CY
, O..Sale_GrossMarginTotal_CY
, O.IncomingOrderType_CY
from OrderTypeTable O
join live.DimSalesRep R on R.SalesRepKey = O.SalesRepKey
order by
O.Sale_Revenue_CY desc
, O.Sale_Revenue_LY desc
, R.SalesRepId
The solution is with using row_number() function in the inner query of the first CTE:
(
select *, row_number() over (partition by x0.CustomerKey order by x0.Sale_Revenue desc) as rn
from
(
select fs.CustomerKey, iot.IncomingOrderTypeKey,
sum(fs.Sale_Revenue) as Sale_Revenue
FROM [dwh01].[live].DimIncomingOrderType iot
join live.FactSales fs
on iot.IncomingOrderTypeKey = fs.IncomingOrderTypeKey
join live.DimDate d
on d.DateId = fs.PostingDateKey
where d.[year] = #CurrentYear
GROUP BY fs.CustomerKey, iot.IncomingOrderTypeKey
) as x0
) as x1 on x1.CustomerKey = s.CustomerKey
The row_number() function gets only the first row from the result for each customer, and that is with the biggest sale revenue ( order by sale_revenue desc).

SQl query optimzation

*can anyone help me optimizing the query. I am using this query in an ETL called streamsets and it is yielding 70 records for 6 minutes when i run an streamsets pipleline which is very slow.we are taking this query from an SSIS package and joining each of the tables using left outer joins.I need to optimize it so that it fetches atleast 1000 records per minute in streamsets *
SELECT [FR].[ORDER_ID]
, [FR].[FULFILLMENT_REQUEST_ID]
, [SR].[SCREENING_RESULT_ID]
, [AT].[AG_TASK_ID]
, [RCC].[RESULT_CRIM_CASE_ID]
, [RCC].[RESULT_CRIM_CHARGE_ID]
, [FR].[JURISDICTION_ID]
, [COUNTY] = CASE WHEN [FR].[PRODUCT_ID] = 2 THEN [JC].[COUNTY_NAME] ELSE '' END
, [STATE] = CASE WHEN [FR].[PRODUCT_ID] = 2 THEN [JC].[STATE_A2_CD] ELSE [JS].[STATE_A2_CD] END
, [JT].[JURISDICTION_TYPE_NAME]
, [FR].[PRODUCT_ID]
, [P].[PRODUCT_NAME]
, [FR].[ORGANIZATION_ID]
, [O].[ORGANIZATION_NAME]
, [SA].[SALARY_RANGE]
, [AGE] = YEAR(GETDATE()) - YEAR([FR].[SUBJECT_DOB])
, [FR].[SUBJECT_JOB_COUNTRY]
, [FR].[SUBJECT_JOB_STATE]
, [FR].[ENTRY_DATE]
, [FR].[CREATION_DATE]
, [FR].[CLOSED_DATE]
, [FR].[EXTERNAL_USER_ID]
, [FR].[GENDER_CODE_ID]
, [GC].[GENDER_CODE_VALUE]
, [AT].[DATA_SOURCE]
, [SU].[RESEARCHER_CLASS]
, [TT].[TASK_TYPE]
, [TT].[TASK_DESCRIPTION]
, [RCC].[CHARGE_DESCRIPTION]
, [RCC].[DISPOSITION_DESCRIPTION]
, [P].[GENERAL_LEDGER_NBR]
, [O].[SCHEME_AGENCY_ID]
, [RT].[RESULT_TYPE_ID]
, [RT].[RESULT_CATEGORY]
, [RT].[RESULT_TYPE]
, [SU].[USER_ID]
,FR.AG_STATUS_ID
, [SCREENING_REFERENCE_ID]=CAST(LEFT([FR].[SCREENING_REFERENCE_ID],250) AS VARCHAR(8000))
,[P1].POD_NAME
, ATH.AG_TASK_HISTORY_ID
,ATH.TASK_STATUS TASK_HISTORY_STATUS
, ATH.AG_TASK_DATE TASK_HISTORY_DATE
,[TT].[TASK_TYPE_ID]
,ATH.MODIFIED_BY_SYSTEM_USER_ID
,ATH.CF_SYSTEM_USER_ID
,'' AS [STATUS NOTES]
, FR.SCOPE_OF_SEARCH
, SR.COMMONNAMFLAG
,CASE WHEN SU.RESEARCHER_CLASS = 'EXTERNAL' THEN SU.[USER_ID] END AS VENDOR
, CASE [TT].TASK_TYPE_ID WHEN 14 THEN 'SD IN' WHEN 15 THEN 'MR' WHEN 1 THEN 'ER' END AS [REQUIRED_ACTION]
, CASE
WHEN [TT].TASK_TYPE_ID = 1 THEN
CASE ATH.TASK_STATUS
WHEN 'DOCUMENTUPLOADED' THEN 'FMT RECORD ENTRY'
WHEN 'ACKNOWLEDGED' THEN 'SEARCHES'
WHEN 'AWAITINGHITENTRY' THEN 'AWAITING HIT'
WHEN 'DISPUTE' THEN 'AWAITING HIT'
WHEN 'DOUBLEENTERRESULTS' THEN 'AWAITING HIT'
WHEN 'NEW' THEN 'SEARCHES'
WHEN 'SOURCEUNAVAILABLE' THEN 'SEARCHES'
WHEN 'UPLOADED' THEN 'SEARCHES'
END
WHEN [TT].TASK_TYPE_ID = 15 THEN
CASE ATH.TASK_STATUS
WHEN 'DISPUTE' THEN 'QC'
WHEN 'DOCUMENTUPLOADED' THEN 'QC'
WHEN 'DOUBLESMARTDATAREVIEW' THEN 'QC'
WHEN 'MANUALREVIEW' THEN 'QC'
END
WHEN [TT].TASK_TYPE_ID = 14 THEN
CASE ATH.TASK_STATUS
WHEN 'DISPUTE' THEN 'QC'
WHEN 'INFONEEDED' THEN 'QC'
WHEN 'INFOPROVIDED' THEN 'QC'
WHEN 'INFONEEDEDACK' THEN 'QC'
WHEN 'NEW' THEN 'QC'
WHEN 'SDINFONEEDED' THEN 'CD COMPLIANCE'
END
END AS [AOM STATUS]
, CASE
WHEN [TT].TASK_TYPE_ID = 1 AND
ATH.TASK_STATUS = 'DOCUMENTUPLOADED' AND
ATH.MODIFIED_BY_SYSTEM_USER_ID IS NOT NULL AND
ATH.CF_SYSTEM_USER_ID IS NOT NULL THEN 'ER DOCUMENT UPLOADED COMPLETE'
WHEN [TT].TASK_TYPE_ID = 14 AND
ATH.TASK_STATUS = 'INFONEEDED' THEN 'SD INFO NEEDED INFO NEEDED DATA'
WHEN [TT].TASK_TYPE_ID = 1 AND SU.RESEARCHER_CLASS = 'INTERNAL' AND
FR.AG_STATUS_ID NOT IN (152) THEN 'ER INTERNAL'
WHEN [TT].TASK_TYPE_ID = 1 AND
ATH.TASK_STATUS = 'AWAITINGHITENTRY' AND
ATH.MODIFIED_BY_SYSTEM_USER_ID IS NOT NULL AND
ATH.CF_SYSTEM_USER_ID IS NOT NULL AND
ATH.MODIFIED_BY_SYSTEM_USER_ID = ATH.CF_SYSTEM_USER_ID THEN 'ER AWAITING HIT ENTRY DATA'
WHEN [TT].TASK_TYPE_ID = 14 THEN 'SD INFO NEEDED DATA'
WHEN [TT].TASK_TYPE_ID = 15 AND
ATH.TASK_STATUS = 'INFONEEDED' THEN 'MR INFO NEEDED'
END AS AG_OPS_STATUS
, FR.EXTERNAL_ORDER_ID
, AOT.OTD
, drv_pod_name=[P1].POD_NAME
, TAT_IN_MIN= Case when TAT_IN_MIN < 0 then 0 else TAT_IN_MIN end
, SU2.USER_ID CF_SYS_USER
, SU3.USER_ID MODIFIED_SYS_USER
, GETDATE() GET_DATE
FROM AG_TASK_HISTORY [ATH] LEFT OUTER JOIN
(
(
(
(
(
(
(
(
(
SELECT [ORDER_ID] ,[FULFILLMENT_REQUEST_ID],[JURISDICTION_ID],[PRODUCT_ID],[ORGANIZATION_ID],[SUBJECT_DOB],[SUBJECT_JOB_COUNTRY],[SUBJECT_JOB_STATE],[ENTRY_DATE],[CREATION_DATE],[CLOSED_DATE],[EXTERNAL_USER_ID],[GENDER_CODE_ID],AG_STATUS_ID,[SCREENING_REFERENCE_ID],SCOPE_OF_SEARCH,EXTERNAL_ORDER_ID,POD_ID,[SALARY_RANGE_ID],[JURISDICTION_TYPE]
FROM [FULFILLMENT_REQUEST]
) FR
LEFT JOIN
(
(SELECT [SCREENING_RESULT_ID],[RESULT_TYPE_ID],[FULFILLMENT_REQUEST_ID],COMMONNAMFLAG FROM [SCREENING_RESULT] )[SR]
INNER JOIN [DBO].[RESULT_TYPE] [RT]
ON [RT].[RESULT_TYPE_ID] = [SR].[RESULT_TYPE_ID]
)
ON [SR].[FULFILLMENT_REQUEST_ID] = [FR].[FULFILLMENT_REQUEST_ID]
)
INNER JOIN [PRODUCT] [P]
ON [P].[PRODUCT_ID] = [FR].[PRODUCT_ID]
INNER JOIN [ORGANIZATION] [O]
ON [O].[ORGANIZATION_ID] = [FR].[ORGANIZATION_ID]
LEFT JOIN(
(SELECT [AG_TASK_ID],[DATA_SOURCE],[TASK_TYPE_ID],[FULFILLMENT_REQUEST_ID],[SYSTEM_USER_ID] FROM [AG_TASK] ) [AT]
INNER JOIN [TASK_TYPE] [TT]
ON [TT].[TASK_TYPE_ID] = [AT].[TASK_TYPE_ID]
)
ON [AT].[FULFILLMENT_REQUEST_ID] = [FR].[FULFILLMENT_REQUEST_ID])
LEFT OUTER JOIN (
(SELECT [RESULT_CRIM_CASE_ID],[SCREENING_RESULT_ID] FROM [RESULT_CRIM_CASE])[RC]
INNER JOIN (SELECT [RESULT_CRIM_CASE_ID],[RESULT_CRIM_CHARGE_ID],[CHARGE_DESCRIPTION],[DISPOSITION_DESCRIPTION] FROM [RESULT_CRIM_CHARGE]) [RCC]
ON [RCC].[RESULT_CRIM_CASE_ID] = [RC].[RESULT_CRIM_CASE_ID]
)
ON [SR].[SCREENING_RESULT_ID] = [RC].[SCREENING_RESULT_ID]
)
)
LEFT JOIN [SYSUSER] [SU]
ON [SU].[SYSTEM_USER_ID] = [AT].[SYSTEM_USER_ID]
LEFT OUTER JOIN [SALARY_RANGE] [SA]
ON [SA].[SALARY_RANGE_ID] = [FR].[SALARY_RANGE_ID]
)
LEFT OUTER JOIN [JURISDICTION_TYPE] [JT]
ON [JT].[JURISDICTION_TYPE_ID] = [FR].[JURISDICTION_TYPE]
)
LEFT OUTER JOIN [GENDER_CODE] [GC]
ON [GC].[GENDER_CODE] = [FR].[GENDER_CODE_ID]
)
LEFT OUTER JOIN [JURISDICTION_COUNTY] [JC]
ON [JC].[JURISDICTION_ID] = [FR].[JURISDICTION_ID]
LEFT OUTER JOIN [JURISDICTION_STATE] [JS]
ON [JS].[JURISDICTION_ID] = [FR].[JURISDICTION_ID]
)
ON [ATH].AG_TASK_ID=[AT].AG_TASK_ID
LEFT OUTER JOIN [POD] [P1] ON [FR].POD_ID = [P1].POD_ID
LEFT OUTER JOIN(
SELECT *, (DATEDIFF(MINUTE, [IN_DATE], [IP_DATE]))-(DATEDIFF(WK, [IN_DATE], [IP_DATE]) * (2*24*60))-
(CASE WHEN DATENAME(DW, [IN_DATE]) = 'SUNDAY'
THEN (24*60) ELSE 0 END)
-(CASE WHEN DATENAME(DW, [IP_DATE]) = 'SATURDAY'
THEN (24*60) ELSE 0 END) TAT_IN_MIN
FROM (
SELECT FULFILLMENT_REQUEST_ID , MAX([IN_DATE]) [IN_DATE], MAX([IP_DATE]) [IP_DATE]
FROM(
SELECT AG_TASK_HISTORY.FULFILLMENT_REQUEST_ID,
CASE WHEN (AG_TASK_HISTORY.TASK_STATUS='INFONEEDED' OR AG_TASK_HISTORY.TASK_STATUS='NEW') AND (SYSUSER.RESEARCHER_CLASS='EXTERNAL' OR SU1.RESEARCHER_CLASS ='EXTERNAL')
THEN AG_TASK_HISTORY.AG_TASK_DATE END [IN_DATE],
CASE WHEN (AG_TASK_HISTORY.TASK_STATUS='INFOPROVIDED' OR AG_TASK_HISTORY.TASK_STATUS='COMPLETE' OR AG_TASK_HISTORY.TASK_STATUS='DOCUMENTUPLOADED') AND (SYSUSER.RESEARCHER_CLASS='EXTERNAL' OR SU1.RESEARCHER_CLASS ='EXTERNAL')
THEN AG_TASK_HISTORY.AG_TASK_DATE END AS [IP_DATE]
FROM AG_TASK_HISTORY
LEFT JOIN SYSUSER(NOLOCK) ON AG_TASK_HISTORY.CF_SYSTEM_USER_ID = SYSUSER.SYSTEM_USER_ID
LEFT JOIN SYSUSER(NOLOCK) SU1 ON AG_TASK_HISTORY.MODIFIED_BY_SYSTEM_USER_ID = SU1.SYSTEM_USER_ID
WHERE AG_TASK_DATE >=CAST('01-JAN-'+CAST(YEAR(GETDATE())-3 AS CHAR(4))AS DATETIME)
) A GROUP BY FULFILLMENT_REQUEST_ID
)B
)AVT
ON FR.FULFILLMENT_REQUEST_ID = AVT.FULFILLMENT_REQUEST_ID
LEFT OUTER JOIN(
SELECT *, (DATEDIFF(DAY, [IN_DATE], [IP_DATE]))-
(DATEDIFF(WK, [IN_DATE], [IP_DATE]) * (2))-
(CASE WHEN DATENAME(DW, [IN_DATE]) = 'SUNDAY' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(DW, [IP_DATE]) = 'SATURDAY' THEN 1 ELSE 0 END) OTD
FROM
(
SELECT FULFILLMENT_REQUEST_ID , MIN(CREATION_DATE) [IN_DATE], GETDATE() [IP_DATE]
FROM FULFILLMENT_REQUEST WHERE CLOSED_DATE IS NULL AND AG_STATUS_ID NOT IN (29,134,142,152)
GROUP BY FULFILLMENT_REQUEST_ID
)B
) AOT
ON FR.FULFILLMENT_REQUEST_ID = AOT.FULFILLMENT_REQUEST_ID
LEFT OUTER JOIN SYSUSER SU2
ON ATH.CF_SYSTEM_USER_ID=SU2.SYSTEM_USER_ID
LEFT OUTER JOIN SYSUSER SU3
ON ATH.MODIFIED_BY_SYSTEM_USER_ID=SU3.SYSTEM_USER_ID
WHERE SU.RESEARCHER_CLASS='EXTERNAL' AND (AVT.TAT_IN_MIN >0 OR AOT.[IP_DATE] IS NULL)
AND ATH.AG_Task_Date >=' 2017-07-07 09:02:23.050'
If you join tables and subselects you really have to know your indexes.
Use explain to check if there is a problem with using indexes.
It is possible that the query can't be optimized and has to be completely redesigned.
It's very hard to give you definite answer to your question because your query is huge and it will take long time to analyze it.
Here are some suggestions to you:
Get execution plan for it (copy it to SMSS and hit CTRL+L) that might give you suggestions what indexes are missing
Remove all the columns from the select list and leave just SELECT COUNT(*) FROM AG_TASK_HISTORY .... Check if you still have bad performance.
Then go from the bottom and eliminate join by join. After each elimination see if the performance is still bad.
After some eliminations you'll must probably get good time and that's means that you've found at least 1 bottleneck.
Then create a proper index for that and try again from step 2.
Other considerations would be to use stored procedures (if it possible) and split this big query into smaller parts, but I am pretty sure that with proper set of the indexes you can get much better performance than you have now.

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
;

CASE statement returning duplicate rows. I only want 1 row per record

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