I have the following query in SQL.
SELECT cast(A.CodigoArticulo as varchar) CodArticulo
, cast(ap.Codigo as varchar ) CodArtProveedor
, dlp.Precio Publico
, 0 Interior
from Articulos a
join ArticuloProveedores ap on ap.ArticuloId = a.Id
join DetallesListaPrecios DLP on DLP.ArticuloId = A.Id
join ListasPrecios lp on lp.Id = dlp.ListaPreciosId
where lp.Id in ('1')
union all
SELECT cast(A.CodigoArticulo as varchar) CodArticulo
, cast(ap.Codigo as varchar ) CodArtProveedor
, 0
, dlp.Precio
FROM Articulos a
join ArticuloProveedores ap on ap.ArticuloId = a.Id
join DetallesListaPrecios DLP on DLP.ArticuloId = A.Id
join ListasPrecios lp on lp.Id = dlp.ListaPreciosId
where lp.Id in ('4')
And the results I get are something like below:
CodArticulo CodArtProveedor Publico Interior
44380 K-7 697 0
44380 K-7 0 767
00003 IM2757 0 2030
00003 IM2757 1845 0
00006 MTRJ6 156 0
00006 MTRJ6 0 172
00010 BERJ6 156 0
00010 BERJ6 0 172
I need to SUM () the columns PUBLICO and INTERIOR. And I my desired output is something like below.
CodArticulo CodArtProveedor Publico Interior
44380 K-7 697 767
00003 IM2757 1845 2030
00006 MTRJ6 156 172
00010 BERJ6 156 172
What are the suggested methods to get my output as expected?
I would suggest the CTE
;WITH cte(CodArticulo,CodArtProveedor,Publico,Interior) AS
(SELECT cast(A.CodigoArticulo as varchar) CodArticulo
, cast(ap.Codigo as varchar ) CodArtProveedor
, dlp.Precio Publico
, 0 Interior
from Articulos a
join ArticuloProveedores ap on ap.ArticuloId = a.Id
join DetallesListaPrecios DLP on DLP.ArticuloId = A.Id
join ListasPrecios lp on lp.Id = dlp.ListaPreciosId
where lp.Id in ('1')
union all
SELECT cast(A.CodigoArticulo as varchar) CodArticulo
, cast(ap.Codigo as varchar ) CodArtProveedor
, 0
, dlp.Precio
FROM Articulos a
join ArticuloProveedores ap on ap.ArticuloId = a.Id
join DetallesListaPrecios DLP on DLP.ArticuloId = A.Id
join ListasPrecios lp on lp.Id = dlp.ListaPreciosId
where lp.Id in ('4'))
select CodArticulo,CodArtProveedor,SUM(Publico),Sum(Interior) from cte group by CodArticulo,CodArtProveedor
I would suggest to input these UNION results to a temp table ##tempResults and then use Group By and Sum
select CodArticulo, CodArtProveedor,SUM(Publico) ,SUM(Interior) from ##tempResults
group by CodArticulo,CodArtProveedor
I'm not completely familiar with your data model, however based on the query, placing a condition inside the SUM may allow you to do the query in a single pass. In the below example a single select (no union) is executed, and a CASE statement is being used inside the SUM to get the desired result:
SELECT cast(A.CodigoArticulo as varchar) CodArticulo
,cast(ap.Codigo as varchar ) CodArtProveedor
,SUM(CASE WHEN '1' THEN dlp.Precio ELSE 0 END) Publico
,SUM(CASE WHEN '4' THEN dlp.Precio ELSE 0 END) Interior
FROM Articulos a
JOIN ArticuloProveedores ap ON ap.ArticuloId = a.Id
JOIN DetallesListaPrecios DLP ON DLP.ArticuloId = A.Id
JOIN ListasPrecios lp ON lp.Id = dlp.ListaPreciosId
WHERE lp.Id in ('1', '4')
GROUP BY A.CodigoArticulo, ap.Codigo
First of 2 possible answers:
Place your UNION query into a Common Table Expression or Sub-Query, then put the group by condition around the outside. Example Below:
SELECT CodArticulo
,CodArtProveedor
,SUM(Publico) as TotalPublico
,SUM(Interior) as TotalInterior
FROM (
SELECT cast(A.CodigoArticulo as varchar) CodArticulo
,cast(ap.Codigo as varchar ) CodArtProveedor
,dlp.Precio Publico
,0 Interior
FROM Articulos a
JOIN ArticuloProveedores ap ON ap.ArticuloId = a.Id
JOIN DetallesListaPrecios DLP ON DLP.ArticuloId = A.Id
JOIN ListasPrecios lp ON lp.Id = dlp.ListaPreciosId
WHERE lp.Id in ('1')
UNION ALL
SELECT cast(A.CodigoArticulo as varchar) CodArticulo
,cast(ap.Codigo as varchar ) CodArtProveedor
,0
,dlp.Precio
FROM Articulos a
JOIN ArticuloProveedores ap ON ap.ArticuloId = a.Id
JOIN DetallesListaPrecios DLP ON DLP.ArticuloId = A.Id
JOIN ListasPrecios lp ON lp.Id = dlp.ListaPreciosId
WHERE lp.Id in ('4')
) d
GROUP BY CodArticulo, CodArtProveedor
This is your query into #Temp
SELECT cast(A.CodigoArticulo as varchar) CodArticulo
, cast(ap.Codigo as varchar ) CodArtProveedor
, dlp.Precio Publico
, 0 Interior
INTO #TEMP
from Articulos a
join ArticuloProveedores ap on ap.ArticuloId = a.Id
join DetallesListaPrecios DLP on DLP.ArticuloId = A.Id
join ListasPrecios lp on lp.Id = dlp.ListaPreciosId
where lp.Id in ('1')
union all
SELECT cast(A.CodigoArticulo as varchar) CodArticulo
, cast(ap.Codigo as varchar ) CodArtProveedor
, 0
, dlp.Precio
FROM Articulos a
join ArticuloProveedores ap on ap.ArticuloId = a.Id
join DetallesListaPrecios DLP on DLP.ArticuloId = A.Id
join ListasPrecios lp on lp.Id = dlp.ListaPreciosId
where lp.Id in ('4')
This is you have to add, that's all.
select sum(Publico),sum(Interior), CodArticulo, CodArtProveedor
from #TEMP
group by CodArticulo, CodArtProveedor
Related
I am trying to execute the below script but a, unsure how to combine the aggregate select statement.
I am trying to add the subquery to sum the amount of parts within the fsl. I am getting the following errors:
Msg 8120, Level 16, State 1, Line 17 Column 'Customer.CustInvId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 16 Column 'dbo.FSLMaster.FSLId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Can someone please help me be able to execute this? Thank you so much!
P.S.Feel free to tell me I am horrible at explaining and I will do my best to give more details to what I am doing
SELECT c.CustCode
, na.NatName
, c.[Name]
, fm.Code
, fm.FSLName
, cfs.SquareFeet AS 'SQFT'
, CONCAT(a.AddrLine1,',', a.City,',', a.StateAbbr,',', a.ZipCode,',', a.CountryId) AS 'Full Adrress'
, a.AddrLine1
, a.City
, a.StateAbbr
, a.ZipCode
, a.CountryId
, a.Longitude
, a.Latitude
,
(
SELECT ISNULL(SUM(ISNULL(OnHandQty,0) - (ISNULL(ReservedQty,0) )),0) FROM dbo.FSLStock WITH (NOLOCK) WHERE FSLStock.FSLId = FM.FSLId
AND PartMasterId IN ( SELECT PartMasterId FROM dbo.PartMaster P WITH (NOLOCK) WHERE P.CustInvId=C.CustInvId)) AS IOH
FROM Customer C WITH(NOLOCK)
INNER JOIN dbo.CustInvProfile CP WITH(NOLOCK) ON C.CustCode = CP.CustCode AND C.ValidTo IS NULL
INNER JOIN dbo.CustFSLAssociation CF WITH(NOLOCK) ON CF.CustInvId = CP.CustInvId AND CF.ValidTo IS NULL
INNER JOIN dbo.FSLMaster FM WITH(NOLOCK) ON FM.FSLId = CF.FSLId AND (COALESCE(FM.ValidTo,getutcdate()) >= getutcdate())
LEFT JOIN CustFSLStrgDtl CFS WITH(NOLOCK) ON cfs.CustInvId = CF.CustInvId and cfs.FSLId = CF.FSLId
LEFT JOIN [Address] a ON fm.AddrId = a.AddrId
LEFT JOIN NationalAccount na ON c.NatAccountId = na.NatAccountId
LEFT JOIN FSLStock fs ON fm.FSLId = fs.FSLId
GROUP BY c.CustCode, na.NatName, c.[Name], fm.Code, fm.FSLName, cfs.SquareFeet, a.AddrLine1, a.City, a.StateAbbr, a.ZipCode, a.CountryId, a.Longitude, a.Latitude
You can use distinct instead to remove duplicates :
select distinct c.CustCode, na.NatName, c.[Name], fm.Code, fm.FSLName,
. . .
from Customer C inner join
dbo.CustInvProfile CP
on . . .
Note : NOLOCK reads dirty data (uncommitted). Please be aware.
You should be using Group by only when you need some kind of aggregation done at the grouped up levels. You don't actually need the subquery, you can convert it into a join:
SELECT c.CustCode
, na.NatName
, c.[Name]
, fm.Code
, fm.FSLName
, cfs.SquareFeet AS 'SQFT'
, CONCAT(a.AddrLine1,',', a.City,',', a.StateAbbr,',', a.ZipCode,',', a.CountryId) AS 'Full Adrress'
, a.AddrLine1
, a.City
, a.StateAbbr
, a.ZipCode
, a.CountryId
, a.Longitude
, a.Latitude
, SUM(CASE WHEN P.Partmasterid is not null then ISNULL(SUM(ISNULL(OnHandQty,0) - (ISNULL(ReservedQty,0) )),0) else 0 end) as IOH
FROM Customer C WITH(NOLOCK)
INNER JOIN dbo.CustInvProfile CP WITH(NOLOCK) ON C.CustCode = CP.CustCode AND C.ValidTo IS NULL
INNER JOIN dbo.CustFSLAssociation CF WITH(NOLOCK) ON CF.CustInvId = CP.CustInvId AND CF.ValidTo IS NULL
INNER JOIN dbo.FSLMaster FM WITH(NOLOCK) ON FM.FSLId = CF.FSLId AND (COALESCE(FM.ValidTo,getutcdate()) >= getutcdate())
LEFT JOIN CustFSLStrgDtl CFS WITH(NOLOCK) ON cfs.CustInvId = CF.CustInvId and cfs.FSLId = CF.FSLId
LEFT JOIN [Address] a ON fm.AddrId = a.AddrId
LEFT JOIN NationalAccount na ON c.NatAccountId = na.NatAccountId
LEFT JOIN FSLStock fs ON fm.FSLId = fs.FSLId
LEFT JOIN PartMaster P ON P.CustInvId=C.CustInvId
GROUP BY c.CustCode, na.NatName, c.[Name], fm.Code, fm.FSLName, cfs.SquareFeet, a.AddrLine1, a.City,
a.StateAbbr, a.ZipCode, a.CountryId, a.Longitude, a.Latitude
If you think, no aggregation is needed, you can simply remove the group by statement. Hope this helps.
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
I have a query as below:
SELECT
cc.chain_desc as chain_desc
,cc.chain_id as chain_id
,COUNT(distinct t.trans_id) as TranCount
FROM TRANSACTION AS t
LEFT OUTER JOIN location AS l
ON t.location_id = l.location_id
LEFT OUTER JOIN trans_line AS tl
ON t.trans_id = tl.trans_id
LEFT OUTER JOIN contract as c
ON t.contract_id = c.contract_id
LEFT OUTER JOIN chain_desc as cc
ON l.chain_id = cc.chain_id
WHERE
t.loc_country = 'U'
AND c.issuer_id IN (156966,166203)
AND t.trans_date >= '2016-10-01 00:00'
and t.trans_date < '2016-10-31 00:00'
AND tl.cat NOT IN ('DEF','DEFD','DEFC')
GROUP BY cc.chain_desc, cc.chain_id
UNION
SELECT
'TOTAL'
,0
,COUNT(distinct t.trans_id)
FROM TRANSACTION AS t
LEFT OUTER JOIN location AS l
ON t.location_id = l.location_id
LEFT OUTER JOIN trans_line AS tl
ON t.trans_id = tl.trans_id
LEFT OUTER JOIN contract as c
ON t.contract_id = c.contract_id
LEFT OUTER JOIN chain_desc as cc
ON l.chain_id = cc.chain_id
WHERE
t.loc_country = 'U'
AND c.issuer_id IN (156966,166203)
AND t.trans_date >= '2016-10-01 00:00'
and t.trans_date < '2016-10-31 00:00'
AND tl.cat NOT IN ('DEF','DEFD','DEFC')
The above query when executed reurns the below result:
I need the result to be displayed as below:
The column "Chain_Id" is of "integer" type, how can I make that blank?.
you can simply select null
.....
UNION
SELECT
'TOTAL'
, NULL::INTEGER
,COUNT(distinct t.trans_id)
FROM TRANSACTION AS t
LEFT OUTER JOIN location AS l
ON t.location_id = l.location_id
LEFT OUTER JOIN trans_line AS tl
ON t.trans_id = tl.trans_id
LEFT OUTER JOIN contract as c
ON t.contract_id = c.contract_id
LEFT OUTER JOIN chain_desc as cc
ON l.chain_id = cc.chain_id
WHERE
t.loc_country = 'U'
AND c.issuer_id IN (156966,166203)
AND t.trans_date >= '2016-10-01 00:00'
and t.trans_date < '2016-10-31 00:00'
AND tl.cat NOT IN ('DEF','DEFD','DEFC')
because null is not a type you could try add above the first query
DEFINE test INT;
LET test = NULL;
......
SELECT
'TOTAL'
, test
,COUNT(distinct t.trans_id)
.....
Or like suggusted by #Jonathan Leffler use NULL::INTEGER or CAST(NULL AS INTEGER)
In Informix you can use NULL in the projection list, but the column must have a type. Since in Informix NULL does not have a type, you need to use a CAST.
SELECT NULL::INTEGER AS id FROM systables WHERE tabid = 1;
SELECT CAST(NULL AS INTEGER) AS id FROM systables WHERE tabid = 1;
You can check the answers to this other question (Informix: Select null problem).
You can check the IBM Knowledge Center (NULL Keyword).
One way is to convert to NULL:
(case when cc.chain_id <> 0 then cc.chain_id end) as chain_id
Another is to convert everything to a string:
(case when cc.chain_id <> 0 then cast(cc.chain_id as varchar(255)) else '' end) as chain_id
I'm trying to do some sort of "if" statement in my where clause. I realize that sql doesn't support this but I'm sure there must be some way to make this work with sql syntax. As shown in the area I have in bold I'm trying to find all items that begin with d and filter them out if their userfld2 also = container.
Is there a more reasonable way to do this than I am doing or am I way off the mark?
Thanks in advance.
Select a.ItemID
, b.ConversionFactor VCaseAmt
, sum(c.ConversionFactor + 1) SCaseAmt
, a.status
, a.UserFld2
From timItem a
inner join timItemUnitOfMeas b on a.ItemKey = b.ItemKey
and b.TargetUnitMeasKey = 115
left join timItemUnitOfMeas c on a.ItemKey = c.ItemKey
and c.TargetUnitMeasKey = 116
left join timItemUnitOfMeas d on a.ItemKey = d.ItemKey
and d.TargetUnitMeasKey = 126
Where d.TargetUnitMeasKey is null
and b.ConversionFactor != c.ConversionFactor + 1
and a.Status = 1
and **(filter a.itemid not like 'd%' when a.userfld2 = 'Container')**
Group by a.ItemID, b.TargetUnitMeasKey, b.ConversionFactor, C.TargetUnitMeasKey
, c.ConversionFactor, a.status, a.UserFld2
Order by a.ItemID
Use this:
Select a.ItemID, b.ConversionFactor VCaseAmt, sum(c.ConversionFactor + 1) SCaseAmt, a.status, a.UserFld2
From timItem a inner join
timItemUnitOfMeas b on a.ItemKey = b.ItemKey and b.TargetUnitMeasKey = 115 left join
timItemUnitOfMeas c on a.ItemKey = c.ItemKey and c.TargetUnitMeasKey = 116 left join
timItemUnitOfMeas d on a.ItemKey = d.ItemKey and d.TargetUnitMeasKey = 126
Where d.TargetUnitMeasKey is null and b.ConversionFactor != c.ConversionFactor + 1 and a.Status = 1 and
not (a.itemid like 'd%' AND a.userfld2 = 'Container')
Group by a.ItemID, b.TargetUnitMeasKey, b.ConversionFactor, C.TargetUnitMeasKey, c.ConversionFactor, a.status, a.UserFld2
Order by a.ItemID
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.