Please check the Microsoft SQL StoredProcedure query bellow. With this query i am getting very slow to complete the process. For only 1000/2000 records taking over 20 sec of time to execute. Now my question is how can i tweak this query to improve its performance? I dont need whole working query but i need advice from expert that what can i do to improve its performance? Is there any better short way to write this same query? Please advice. Thanks in advance
Poor Performance SQL:
USE [Analytics]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [vision].[SancusoReferralExceptionsReport]
as
begin
Declare #programid varchar(30) ;
DECLARE #Startdate DATETIME = '1900-01-01'
set #programid = '31';
;
with ProgramExceptions as
(
-- 1. Referring contact name should not be blank
select 'Referral Pharmacy Contact Name should not be blank' as ExceptionReason
, a.AspnRxID
, ap.PrescriptionID
from [ArmadaRX].aspn.ASPNRX a
left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = a.AspnRxID
where a.ProgramID in (31)
and (#Startdate is null or (a.CreatedOn between #Startdate and getdate()))
and (a.ReferringPharmacyContact is null or rtrim(ltrim(a.ReferringPharmacyContact)) = '')
union
-- 2. Received/Referral Date should not be blank
select 'Received/Referral date should not be blank' as ExceptionReason
, a.AspnRxID
, ap.PrescriptionID
from [ArmadaRX].aspn.ASPNRX a
left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = a.AspnRxID
where a.ProgramID in (31)
and (#Startdate is null or (a.CreatedOn between #Startdate and getdate()))
and a.ReceivedOn is null
) /* end of CTE */
select distinct
pe.ExceptionReason
, pe.AspnRxID
, a.ProgramID
, prg.ProgramName
, coalesce(cp.ReferralType,a.ReferralType) ReferralType
, a.RxType
, a.ProgramStatus
, a.ProgramSubstatus
, a.ReceivedOn as ReceivedOnDate
, a.PrescriptionDate
, ap.FillDate
, ap.ShipDate
, cp.Quantity as PrescriptionQuantity
, ap.FillQty
, ap.Indicator
, a.CreatedOn as CreateDate
, a.ModifiedOn as ModifyDate
, a.AssignedOn as AssignDate
, a.AcceptedOn as AcceptDate
, a.CompletedOn as CompleteDate
, a.CancelledOn as CancelDate
, a.FillingPharmacyContact
, a.ReferringPharmacyContact
, m.MemberName as FillingPharmacyName
, m2.MemberName as ReferringPharmacyName
, cp.PrescriptionID
, cp.DrugName
, cp.Copay as PrescriptionCopay
, a.ReferralCode
, (select [TypeCode] from [ArmadaRX].[common].[INSURANCETYPE] where [InsuranceTypeID] = cp.InsuranceType) as InsuranceType
, cp.InsuranceName
, pd.NPI
, cp.Binnumber
from ProgramExceptions pe
inner join [ArmadaRX].aspn.ASPNRX a on a.AspnRxID = pe.AspnRxID
left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = pe.AspnRxID and (pe.PrescriptionID is null or ap.PrescriptionID = pe.PrescriptionID)
left outer join [ArmadaRX].common.PRESCRIPTION cp on cp.PrescriptionID = ap.PrescriptionID and (pe.PrescriptionID is null or cp.PrescriptionID = pe.PrescriptionID)
left outer join ArmadaRX.aspn.PRESCRIPTIONDOCTOR pd on pd.PrescriptionID = cp.PrescriptionID
left outer join [ArmadaRX].common.Patient p on p.patientID = a.PatientID
left outer join [ArmadaRX].aspn.Program prg on prg.ProgramID = a.ProgramID
left outer join ArmadaApproveRx.dbo.vMember m on m.MemberID = a.FillingPharmacyID
left outer join ArmadaApproveRx.dbo.vMember m2 on m2.MemberID = a.ReferringPharmacyID
where a.ProgramID in (31)
order by pe.AspnRxID
end
In my experience, using CTEs for large datasets degrades the performance of the query. In switching CTEs to Temp tables, I have found large performance improvements as this does give me the ability to create indexes as needed. The code below is an example of transforming the OPs example query with a CTE to use a temp table.
USE [Analytics]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [vision].[SancusoReferralExceptionsReport]
as
begin
Declare #programid varchar(30) ;
DECLARE #Startdate DATETIME = '1900-01-01'
set #programid = '31';
SELECT *
INTO #TempTable
FROM (
-- 1. Referring contact name should not be blank
select 'Referral Pharmacy Contact Name should not be blank' as ExceptionReason
, a.AspnRxID
, ap.PrescriptionID
from [ArmadaRX].aspn.ASPNRX a
left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = a.AspnRxID
where a.ProgramID in (31)
and (#Startdate is null or (a.CreatedOn between #Startdate and getdate()))
and (a.ReferringPharmacyContact is null or rtrim(ltrim(a.ReferringPharmacyContact)) = '')
union
-- 2. Received/Referral Date should not be blank
select 'Received/Referral date should not be blank' as ExceptionReason
, a.AspnRxID
, ap.PrescriptionID
from [ArmadaRX].aspn.ASPNRX a
left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = a.AspnRxID
where a.ProgramID in (31)
and (#Startdate is null or (a.CreatedOn between #Startdate and getdate()))
and a.ReceivedOn is null
) AS T
select distinct
pe.ExceptionReason
, pe.AspnRxID
, a.ProgramID
, prg.ProgramName
, coalesce(cp.ReferralType,a.ReferralType) ReferralType
, a.RxType
, a.ProgramStatus
, a.ProgramSubstatus
, a.ReceivedOn as ReceivedOnDate
, a.PrescriptionDate
, ap.FillDate
, ap.ShipDate
, cp.Quantity as PrescriptionQuantity
, ap.FillQty
, ap.Indicator
, a.CreatedOn as CreateDate
, a.ModifiedOn as ModifyDate
, a.AssignedOn as AssignDate
, a.AcceptedOn as AcceptDate
, a.CompletedOn as CompleteDate
, a.CancelledOn as CancelDate
, a.FillingPharmacyContact
, a.ReferringPharmacyContact
, m.MemberName as FillingPharmacyName
, m2.MemberName as ReferringPharmacyName
, cp.PrescriptionID
, cp.DrugName
, cp.Copay as PrescriptionCopay
, a.ReferralCode
, (select [TypeCode] from [ArmadaRX].[common].[INSURANCETYPE] where [InsuranceTypeID] = cp.InsuranceType) as InsuranceType
, cp.InsuranceName
, pd.NPI
, cp.Binnumber
from #TempTable pe
inner join [ArmadaRX].aspn.ASPNRX a on a.AspnRxID = pe.AspnRxID
left outer join [ArmadaRX].aspn.ASPNRX_PRESCRIPTION ap on ap.AspnRxID = pe.AspnRxID and (pe.PrescriptionID is null or ap.PrescriptionID = pe.PrescriptionID)
left outer join [ArmadaRX].common.PRESCRIPTION cp on cp.PrescriptionID = ap.PrescriptionID and (pe.PrescriptionID is null or cp.PrescriptionID = pe.PrescriptionID)
left outer join ArmadaRX.aspn.PRESCRIPTIONDOCTOR pd on pd.PrescriptionID = cp.PrescriptionID
left outer join [ArmadaRX].common.Patient p on p.patientID = a.PatientID
left outer join [ArmadaRX].aspn.Program prg on prg.ProgramID = a.ProgramID
left outer join ArmadaApproveRx.dbo.vMember m on m.MemberID = a.FillingPharmacyID
left outer join ArmadaApproveRx.dbo.vMember m2 on m2.MemberID = a.ReferringPharmacyID
where a.ProgramID in (31)
order by pe.AspnRxID
DROP TABLE #TempTable
end
Related
I do have a problem on how to insert numerous rows of data into a table from an existing table with conditions. So this first code is how I created my table.
CREATE TABLE MARKETING_COMMODITY
AS(
SELECT A.DTIME_SIGNATURE
, A.AMT_SIGNED
, A.CNT_SIGNED
, A.APPLICATION_AMOUNT
, A.PRODUCT
, A.PRODUCT_TYPE
, A.PRODUCT_PRICE
, VSR.NAME_PRODUCER
, vsr.text_model_number
, vsp.partner_name
, vsp.partner_brand
, vspl.salesroom
, vspl.mall
FROM DM_SALES.V_SALES_DM_DATA A
LEFT JOIN DM_SALES.V_SALES_DM_PARTNER VSP ON A.CODE_SALESROOM_PARTNER = VSP.CODE_SALESROOM_PARTNER
LEFT JOIN dm_sales.v_sales_dm_pos_list vspl on a.code_salesroom = vspl.code_salesroom
LEFT JOIN DM_SALES.V_SALES_DM_CONTRACT_BUNDLE VSR ON A.CONTRACT_NUMBER = VSR.CONTRACT_NUMBER
WHERE 1=1
AND a.contract_state <> 'Cancelled'
AND a.cnt_signed=1
AND A.LOAN_TYPE = 'Consumer Loan'
AND (TRUNC(A.DTIME_SIGNATURE) BETWEEN DATE'2022-01-01' AND DATE'2022-08-31')
;
And this is how I'd like to insert my new rows (its like updating the table to get the new data up to the current day)
INSERT INTO MARKETING_COMMODITY
VALUES(
SELECT A.DTIME_SIGNATURE
, A.AMT_SIGNED
, A.CNT_SIGNED
, A.APPLICATION_AMOUNT
, A.PRODUCT
, A.PRODUCT_TYPE
, A.PRODUCT_PRICE
, VSR.NAME_PRODUCER
, vsr.text_model_number
, vsp.partner_name
, vsp.partner_brand
, vspl.salesroom
, vspl.mall
FROM DM_SALES.V_SALES_DM_DATA A
LEFT JOIN DM_SALES.V_SALES_DM_PARTNER VSP ON A.CODE_SALESROOM_PARTNER = VSP.CODE_SALESROOM_PARTNER
LEFT JOIN dm_sales.v_sales_dm_pos_list vspl on a.code_salesroom = vspl.code_salesroom
LEFT JOIN DM_SALES.V_SALES_DM_CONTRACT_BUNDLE VSR ON A.CONTRACT_NUMBER = VSR.CONTRACT_NUMBER
WHERE 1=1
AND a.contract_state <> 'Cancelled'
AND a.cnt_signed=1
AND A.LOAN_TYPE = 'Consumer Loan'
AND (TRUNC(A.DTIME_SIGNATURE) BETWEEN DATE'2022-09-01' AND DATE'2022-09-10')
;
What can you suggest? Thanks!
Don't confuse the syntax for "CREATE TABLE AS SELECT" with the syntax for "INSERT INTO SELECT". Explicitely add the columns you're inserting into and remove the "AS" keyword. This should work:
INSERT INTO MARKETING_COMMODITY
(
dtime_signature
,amt_signed
,cnt_signed
,application_amount
,product
,product_type
,product_price
,name_producer
,text_model_number
,partner_name
,partner_brand
,salesroom
,mall
)
SELECT A.DTIME_SIGNATURE
, A.AMT_SIGNED
, A.CNT_SIGNED
, A.APPLICATION_AMOUNT
, A.PRODUCT
, A.PRODUCT_TYPE
, A.PRODUCT_PRICE
, VSR.NAME_PRODUCER
, vsr.text_model_number
, vsp.partner_name
, vsp.partner_brand
, vspl.salesroom
, vspl.mall
FROM DM_SALES.V_SALES_DM_DATA A
LEFT JOIN DM_SALES.V_SALES_DM_PARTNER VSP ON A.CODE_SALESROOM_PARTNER = VSP.CODE_SALESROOM_PARTNER
LEFT JOIN dm_sales.v_sales_dm_pos_list vspl on a.code_salesroom = vspl.code_salesroom
LEFT JOIN DM_SALES.V_SALES_DM_CONTRACT_BUNDLE VSR ON A.CONTRACT_NUMBER = VSR.CONTRACT_NUMBER
WHERE 1=1
AND a.contract_state <> 'Cancelled'
AND a.cnt_signed=1
AND A.LOAN_TYPE = 'Consumer Loan'
AND (TRUNC(A.DTIME_SIGNATURE) BETWEEN DATE'2022-09-01' AND DATE'2022-09-10')
;
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.
I have a view which queries around 1+ million rows and takes around 10-15 minutes to finish its execution,I want to provide cluster indexing to it so that it exists in physical schema and takes less time to load, but there are a number of constraints in order to provide cluster indexing i.e. only INNER JOIN are allowed and No subqueries should be present in views defination how do I replace the LEFT JOIN present in this view with INNER JOIN and how do I eliminate subqueries from this views defination so that cluster indexing can be applied to it.
CREATE view [dbo].[FTM_ProfileDetailsView] with SCHEMABINDING as
select FTM.Id
, FTM.EmployeeId
, FTM.CustomerId
, FTM.AbsenceFirstDate
, FTM.BackgroundHistory
, FTM.BackgroundHistoryComments
, FTM.IsEmployeeAbsent,FTM.ServiceId
, Case When isnull(FTM.IsSelfManagement,'')='' THEN cast(0 as bit) ELSE FTM.IsSelfManagement END as IsSelfManagement
, PR.ServiceLineId,FTM.ProfileId,PR.StatusId,Status.Status as StatusName
, PR.ReasonID
, PR.ModifiedDate
, PR.WithdrawnReason
, PR.CreatedBy
, PR.CreatedDate
, PR.IsActive
, mgrs.usernames as LineManagers
, cust.CustomerName
, ltrim(rtrim( emp.EmployeeTitle+' '+ emp.FirstName+' '+ emp.Surname)) as EmployeeFullName
, FTM.ProfileManagerId
, FTM.IsProfileManagement
, AM.MonitoringChecks
, AM.Frequency
, AM.ProfileManagerNotes
, AM.TaskDateAndTime
, FTM.ProfileManagementCriteriaId
,cast(case when PR.StatusId = 13 then 1 else 0 end as bit) as IsActiveMonitoring
, CustServ.CustomerServiceName
, BU.Name as BusinessUnit
, emp.DASID
, emp.DateOfBirth as EmployeeDOB
, addr.PostCode
, coninfo.Email
, (select top 1
StatusId from dbo.PR_Profileintervention ProfileInt
where ProfileInt.ProfileId=FTM.Profileid
order by ProfileInt.Id desc) as LatestInterventionStatusId
, (select name from dbo.FTM_Intervention Intr
where Intr.Id=(select top 1 InterventionId from dbo.PR_Profileintervention ProfileInt
where ProfileInt.ProfileId=FTM.Profileid
order by ProfileInt.Id desc))
as LatestInterventionName from FTM_Profile FTM
LEFT JOIN dbo.ProfileManagersView mgrs ON mgrs.ProfileID = FTM.ProfileID
INNER JOIN dbo.Customer cust on cust.Id= FTM.CustomerId
INNER JOIN dbo.Employee emp on emp.Id = FTM.EmployeeId
INNER JOIN dbo.PR_Profile PR on PR.Profileid=FTM.ProfileId
LEFT JOIN dbo.BusinessUnit BU on BU.Id=PR.BUId
LEFT JOIN dbo.PR_dv_Status [Status] on [Status].Id = PR.StatusId
LEFT JOIN dbo.CM_ActiveMonitoringDetails AM on AM.ProfileId = PR.Profileid
LEFT JOIN dbo.FTM_CustomerServiceMapping CustServ on CustServ.ServiceId = FTM.ServiceId and CustServ.CustomerId = FTM.CustomerId
LEFT JOIN dbo.contact con on con.Id = emp.ContactID
LEFT JOIN dbo.address addr on addr.Id = con.HomeAddressId
LEFT JOIN dbo.contactinfo coninfo on coninfo.Id = con.ContactInfoId
I have a suggestion. Can you try and change your query so the sub -queries in the SELECT are placed in CROSS APPLYs?
So something along the lines of this in your WHERE clause:
CROSS APPLY (
select top 1 StatusId AS LatestInterventionStatusId
from dbo.PR_Profileintervention ProfileInt
where ProfileInt.ProfileId=FTM.Profileid
order by ProfileInt.Id desc
) LatestInterventionStatusId
CROSS APPLY (
select name AS LatestInterventionName
from dbo.FTM_Intervention Intr
where Intr.Id=(select top 1 InterventionId
from dbo.PR_Profileintervention ProfileInt
where ProfileInt.ProfileId=FTM.Profileid
order by ProfileInt.Id desc)
)LatestInterventionName
And then of course change the column names in the SELECT to something like this:
, LatestInterventionStatusId.LatestInterventionStatusId
, LatestInterventionName.LatestInterventionName
Give this a go and let me know if it makes a different.
Ok, you didn't give me an answer on my question, but the subqueries should be changed. Try to use this instead the two subqueries:
/*
...
, emp.DateOfBirth as EmployeeDOB
, addr.PostCode
, coninfo.Email
*/
, p.StatusId as LatestInterventionStatusId
, p.name as LatestInterventionName
from FTM_Profile FTM
OUTER APPLY (
select TOP 1 Intr.name, ProfileInt.StatusId
from dbo.PR_Profileintervention ProfileInt
LEFT JOIN dbo.FTM_Intervention Intr ON Intr.Id = ProfileInt.InterventionId
where ProfileInt.ProfileId = FTM.Profileid
order by ProfileInt.Id desc
) p
/*
LEFT JOIN dbo.ProfileManagersView mgrs ON mgrs.ProfileID = FTM.ProfileID
INNER JOIN dbo.Customer cust on cust.Id= FTM.CustomerId
INNER JOIN dbo.Employee emp on emp.Id = FTM.EmployeeId
...
*/
I have a simple query that I would like some specific results but not sure of the right way to go about it. I'm using a SQL Server database and my query is as follows:
SELECT dt.year ,
db.dist_code ,
db.dist_name ,
db.s_code ,
db.s_name ,
fl.zip ,
fl.num_births ,
total_enrollment
FROM dbo.fact_enrollment_school AS fs
INNER JOIN dbo.dim_building AS db ON fs.building_key = db.building_key
INNER JOIN dbo.dim_time AS dt ON fs.time_key = dt.time_key
LEFT OUTER JOIN dbo.fact_live_birth AS fl ON dt.time_key = fl.time_key
AND db.building_key = fl.building_key
GROUP BY dt.year ,
db.dist_code ,
db.dist_name ,
db.school_code ,
db.school_name ,
fl.zip ,
total_enrollment ,
fl.num_births
What I need is to output the num_births total for every district_code that is the same.
Desired output:
I think you can achieve this by window function:
SELECT dt.year ,
db.dist_code ,
db.dist_name ,
db.s_code ,
db.s_name ,
fl.zip ,
sum(fl.num_births) over (partition by dt.year, db.dist_code),
total_enrollment
FROM dbo.fact_enrollment_school AS fs
INNER JOIN dbo.dim_building AS db ON fs.building_key = db.building_key
INNER JOIN dbo.dim_time AS dt ON fs.time_key = dt.time_key
LEFT OUTER JOIN dbo.fact_live_birth AS fl ON dt.time_key = fl.time_key
AND db.building_key = fl.building_key;
I have 2 queries.
Query # 1: inserts some data into a temp table
Query # 2: inserts the data from the temp table (with some joins) into a new table.
Running Query #1 alone takes 3 seconds. Running Query #2 alone takes 12 seconds.
When I run them both together as one execution, it runs forever (over 4 minutes).
What could possibly be the reason for this?
(I would post my code but it's very long and not much understandable to the outsider.)
Here's my SQL (at your own risk): Remember they run fine when ran alone.
-- START QUERY #1
SELECT * INTO #TempProdForSiteGoingTrim
FROM
(
SELECT
p.idProduct
, p.active
, p.sku
, p.description
, p.listprice
, p.price
, p.imageurl
, p.smallimageurl
, p.idManufacturer
, sortOrder
, CASE WHEN p.pgroup = '' OR p.pgroup IS NULL THEN CAST(p.idProduct AS VARCHAR) ELSE pgroup END [pgroup]
, CASE WHEN pa2.attr IS NULL THEN CAST(p.idProduct AS VARCHAR) ELSE CASE WHEN p.pgroup = '' OR p.pgroup IS NULL THEN CAST(p.idProduct AS VARCHAR) ELSE pgroup END END [RugGroup]
, pa1.attr [Color]
, pa3.attr [Collection]
, pa2.attr [RugSize]
, pa4.attr[RugShape]
FROM
(SELECT DISTINCT idProduct FROM ProdSite WHERE idSite = 39 ) s
INNER JOIN (SELECT * FROM products p WHERE active = -1 ) p ON s.idproduct = p.idproduct
LEFT OUTER JOIN (SELECT t.idproduct, attr FROM (SELECT max(idprodattr) [idprodattr], idproduct, b.idattrset FROM productattr a JOIN product_attr b on a.idattr = b.idattr WHERE idattrset = 1 GROUP BY a.idproduct, b.idattrset )t JOIN productattr a ON t.idprodattr = a.idprodattr JOIN product_attr b ON a.idattr = b.idattr) pa1 ON p.idproduct = pa1.idproduct
LEFT OUTER JOIN (SELECT t.idproduct, attr FROM (SELECT max(idprodattr)[idprodattr], idproduct, b.idattrset FROM productattr a JOIN product_attr b on a.idattr = b.idattr WHERE idattrset = 160 GROUP BY a.idproduct, b.idattrset )t JOIN productattr a ON t.idprodattr = a.idprodattr JOIN product_attr b ON a.idattr = b.idattr) pa2 ON p.idproduct = pa2.idproduct
LEFT OUTER JOIN (SELECT t.idproduct, attr FROM (SELECT max(idprodattr)[idprodattr], idproduct, b.idattrset FROM productattr a JOIN product_attr b on a.idattr = b.idattr WHERE idattrset = 6 GROUP BY a.idproduct, b.idattrset )t JOIN productattr a ON t.idprodattr = a.idprodattr JOIN product_attr b ON a.idattr = b.idattr) pa3 ON p.idproduct = pa3.idproduct
LEFT OUTER JOIN (SELECT t.idproduct, attr FROM (SELECT max(idprodattr)[idprodattr], idproduct, b.idattrset FROM productattr a JOIN product_attr b on a.idattr = b.idattr WHERE idattrset = 62 GROUP BY a.idproduct, b.idattrset )t JOIN productattr a ON t.idprodattr = a.idprodattr JOIN product_attr b ON a.idattr = b.idattr) pa4 ON p.idproduct = pa4.idproduct
)t
-- END QUERY #1
-- START QUERY #2
DECLARE #listRugSizes TABLE (idmanufacturer int, RugGroup VARCHAR(500), RugSizes VARCHAR(1000))
INSERT INTO #listRugSizes
SELECT
t1.idmanufacturer
, t1.RugGroup
, STUFF(( SELECT ', ' + RugSize FROM #TempProdForSiteGoingTrim t2 WHERE t2.RugGroup = t1.RugGroup and t2.idmanufacturer = t1.idmanufacturer FOR XML PATH(''), TYPE ).value('.', 'varchar(max)'), 1, 1, '') [Values]
FROM
#TempProdForSiteGoingTrim t1
GROUP BY
t1.RugGroup
, t1.idmanufacturer
INSERT INTO [NewTableForSiteGoingTrim]
SELECT
p.idProduct
, p.sku
, p.description
, p.listPrice
, p.price
, p.imageUrl
, p.smallImageUrl
, p.sortOrder
, p.idManufacturer
, p.pgroup
, p.ruggroup
, c.idCategory
, c.idCategory [fidcategory]
, c.idParentCategory
, c.idParentCategory [gidcategory]
, pc.idParentCategory [hidCategory]
, ppc.idParentCategory [iidCategory]
, m.Name
, rp.rewrite_key [rewrite_index]
, rm.rewrite_key [rewrite_key]
, color [Color]
, collection [Collection]
, rugsize [RugSize]
, ruggroup.rugcount
, ruggroup.maxprice
, ruggroup.minprice
, rs.RugSizes
, p.rugshape
FROM
#TempProdForSiteGoingTrim p
LEFT OUTER JOIN (
SELECT
MIN(c.idCategory) [idCategory]
, c.idProduct
FROM
(
SELECT
cp.idProduct
, cp.idCategory
FROM
dbo.categories_products cp
JOIN categories c ON cp.idcategory = c.idCategory
WHERE
c.idSite = 24
) c
GROUP BY
c.idProduct
) cp ON p.idProduct = cp.idProduct
LEFT OUTER JOIN categories c ON cp.idCategory = c.idCategory
LEFT OUTER JOIN categories pc ON c.idParentCategory = pc.idCategory
LEFT OUTER JOIN categories ppc ON pc.idParentCategory = ppc.idCategory
LEFT OUTER JOIN manufacturer m ON p.idManufacturer = m.idManufacturer
LEFT OUTER JOIN (SELECT * FROM rewrite WHERE type = 3) rm ON p.idManufacturer = rm.id
LEFT OUTER JOIN (SELECT * FROM rewrite WHERE type = 1) rp ON p.idProduct = rp.id
LEFT OUTER JOIN #listRugSizes rs ON p.RugGroup = rs.RugGroup and p.idmanufacturer = rs.idmanufacturer
LEFT OUTER JOIN
(
SELECT
p.ruggroup
, p.idmanufacturer
, min(price) [minPrice]
, count(*) [RugCount]
, m.maxprice
FROM
#TempProdForSiteGoingTrim p
LEFT OUTER JOIN
(
SELECT
r.ruggroup
, r.idmanufacturer
, max(price) [maxprice]
FROM
#TempProdForSiteGoingTrim r
WHERE
r.idproduct = (SELECT MAX(idproduct) FROM #TempProdForSiteGoingTrim WHERE ruggroup = r.ruggroup AND price = r.price and idmanufacturer = r.idmanufacturer)
GROUP BY
ruggroup
, idmanufacturer
) m ON p.ruggroup = m.ruggroup and p.idmanufacturer = m.idmanufacturer
GROUP BY
p.ruggroup
, m.maxprice
, p.idmanufacturer
) ruggroup ON p.ruggroup = ruggroup.ruggroup and p.idmanufacturer = ruggroup.idmanufacturer
-- END QUERY #2
Edit
When I change the last join "ruggroup" to only group and join by column "ruggroup" and not "ruggroup" and "idmanufacturer" then it works fine.