How to merge null column in sql table - sql-server

I want to merge null column with same username or userid where quarter is different, like if username is same for quarter1,2,3, according to below query it is showing same username with different quarter in different row, but i want in same row with different quarter and same user name
ALTER PROCEDURE [dbo].[test]
--#USERID UNIQUEIDENTIFIER,
#BASESTARTDATE DATE,
#BASEENDDATE DATE,
#CASETYPEID VARCHAR(40),
#GROUPTYPE VARCHAR(40),
#COMPANYID VARCHAR(40),
#DEPTID VARCHAR(40)
AS
BEGIN
SET NOCOUNT ON
--CREATE TEMPORARY TABLE FOR INSERTING CALCULATED QUARTER
CREATE TABLE #QUARTERTEMP(QUARTER VARCHAR(10),STARTDATE DATE,ENDDATE DATE,COUNTROW INT)
DECLARE #STARTDATETEMP DATETIME
DECLARE #ENDDATETEMP DATETIME
DECLARE #COUNTQUARTER INT
DECLARE #COUNTERCOUNT INT
SELECT #STARTDATETEMP=#BASESTARTDATE , #ENDDATETEMP=#BASEENDDATE
;WITH QUARTERS AS (
SELECT DATEADD(QUARTER,DATEDIFF(QUARTER,0,#STARTDATETEMP),0) AS DT,
DATEADD(DD, -1,DATEADD(QQ,DATEDIFF(QQ,0,#STARTDATETEMP)+1,0)) AS DATEEND
UNION ALL
SELECT DATEADD(QUARTER,1,DT),DATEADD(QUARTER,1,DATEEND) FROM QUARTERS
WHERE DT < DATEADD(QUARTER,DATEDIFF(QUARTER,0,#ENDDATETEMP),0)
)
INSERT INTO #QUARTERTEMP
SELECT 'Q' + DATENAME(QQ,DT) + '-' + CAST(RIGHT(YEAR(DT)+ 0,2) AS VARCHAR(50)),DT AS 'STARTDATE',DATEEND AS 'ENDDATE',ROW_NUMBER() OVER (ORDER BY DT)FROM QUARTERS
--SELECT * FROM #QUARTERTEMP
/*DECLARE LOCAL VARIABLES*/
DECLARE #QUARTERNAME AS VARCHAR(10)
DECLARE #BEGINDATE AS DATE
DECLARE #ENDDATE AS DATE
SET #COUNTERCOUNT = 1
SELECT #COUNTQUARTER = COUNT(*) FROM #QUARTERTEMP
DECLARE #RESPONSEVALUE AS DECIMAL(9,1)
DECLARE #COUNT AS INT
DECLARE #ALLAVG AS DECIMAL(9,2)
/*CREATE TEMP TABLE FOR INSERTING ALL RECORDS OF USERS*/
CREATE TABLE #TEMPUSER(USERID UNIQUEIDENTIFIER, USERNAME VARCHAR(100),[QUARTER] VARCHAR(40) NULL,[AVG] DECIMAL (9,2) NULL,[AVGALL] DECIMAL (9,2) NULL)
/*START OF WHILE LOOP*/
WHILE (#COUNTERCOUNT <= #COUNTQUARTER)
BEGIN
/*FETCH QUARTERS TABLE QUARTERWISE*/
SELECT #QUARTERNAME = [QUARTER],#BEGINDATE=STARTDATE,#ENDDATE = ENDDATE FROM #QUARTERTEMP WHERE COUNTROW = #COUNTERCOUNT
print(#BEGINDATE)
print(#ENDDATE)
IF #DEPTID IS NOT NULL
BEGIN
PRINT('IN DEPT')
/*DEPARTMENT AVG*/
CREATE TABLE #TEMPALLUSER(USERID UNIQUEIDENTIFIER, USERNAME VARCHAR(100),[QUARTER] VARCHAR(40) NULL,[AVG] DECIMAL (9,2) NULL,[AVGALL] DECIMAL (9,2) NULL)
SELECT #ALLAVG = ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2) FROM SURVEYRESPONSES SR LEFT OUTER JOIN SURVEYS S
ON SR.SURVEYID = S.SURVEYID
LEFT OUTER JOIN SURVEYTARGETS ST ON S.SURVEYTARGETID = ST.SURVEYTARGETID
LEFT OUTER JOIN USERS U ON ST.IDENTIFICATION = U.USERID
INNER JOIN [DBO].[SURVEYDEFINITIONS] SD ON S.SURVEYDEFINITIONID=SD.SURVEYDEFINITIONID
INNER JOIN [DBO].[PARENTCHILDS] PC ON SD.SURVEYDEFINITIONTYPEID=PC.CHILDID
INNER JOIN [DBO].[MASTERQUESTIONS] M ON SR.MASTERQUESTIONID=M.MASTERQUESTIONID
INNER JOIN [DBO].[QUESTIONGROUPS] Q ON M.QUESTIONGROUPID=Q.QUESTIONGROUPID
--WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=#USERIDENTIFICATION))
WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = #DEPTID)
AND (PC.PARENTID=#CASETYPEID OR PC.CHILDID=#CASETYPEID)
AND (1=CASE WHEN ((#GROUPTYPE= '-1') OR (Q.QUESTIONGROUPID=#GROUPTYPE)) THEN 1 ELSE 0 END)
AND SR.RESPONSEVALUE != -2147483648 AND S.SURVEYSTATUSID IN(6) AND S.SURVEYSTATUSID != 99
AND CAST(S.RESPONSEDATE AS DATE) BETWEEN #BEGINDATE AND #ENDDATE
/*INSERT VALUES IN TEMPALLUSER TABLE*/
INSERT INTO #TEMPALLUSER
SELECT U.USERID,U.NAME1,#QUARTERNAME,ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2),#ALLAVG FROM SURVEYRESPONSES SR LEFT OUTER JOIN SURVEYS S
ON SR.SURVEYID = S.SURVEYID
LEFT OUTER JOIN SURVEYTARGETS ST ON S.SURVEYTARGETID = ST.SURVEYTARGETID
LEFT OUTER JOIN USERS U ON ST.IDENTIFICATION = U.USERID
INNER JOIN [DBO].[SURVEYDEFINITIONS] SD ON S.SURVEYDEFINITIONID=SD.SURVEYDEFINITIONID
INNER JOIN [DBO].[PARENTCHILDS] PC ON SD.SURVEYDEFINITIONTYPEID=PC.CHILDID
INNER JOIN [DBO].[MASTERQUESTIONS] M ON SR.MASTERQUESTIONID=M.MASTERQUESTIONID
INNER JOIN [DBO].[QUESTIONGROUPS] Q ON M.QUESTIONGROUPID=Q.QUESTIONGROUPID
--WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=#USERIDENTIFICATION))
WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = #DEPTID) AND
(PC.PARENTID=#CASETYPEID OR PC.CHILDID=#CASETYPEID)
AND (1=CASE WHEN ((#GROUPTYPE= '-1') OR (Q.QUESTIONGROUPID=#GROUPTYPE)) THEN 1 ELSE 0 END)
AND SR.RESPONSEVALUE != -2147483648 AND S.SURVEYSTATUSID IN(6) AND S.SURVEYSTATUSID != 99
AND CAST(S.RESPONSEDATE AS DATE) BETWEEN #BEGINDATE AND #ENDDATE
GROUP BY U.USERID, U.NAME1
ORDER BY ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2) DESC
INSERT INTO #TEMPUSER
SELECT * FROM #TEMPALLUSER
print(#COUNT)
SELECT #COUNT = COUNT(*) FROM #TEMPALLUSER
IF #COUNT = 0
BEGIN
INSERT INTO #TEMPUSER VALUES(NULL,'',#QUARTERNAME,0.0,0.0)
END
DROP TABLE #TEMPALLUSER
END /*END OF IF LOOP (DEPTID IS NOT NULL)*/
ELSE /*START OF ELSE CONDITION*/
BEGIN
PRINT('IN COMP')
/*COMPANY AVG*/
SELECT #ALLAVG = ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2) FROM SURVEYRESPONSES SR LEFT OUTER JOIN SURVEYS S
ON SR.SURVEYID = S.SURVEYID
LEFT OUTER JOIN SURVEYTARGETS ST ON S.SURVEYTARGETID = ST.SURVEYTARGETID
LEFT OUTER JOIN USERS U ON ST.IDENTIFICATION = U.USERID
INNER JOIN [DBO].[SURVEYDEFINITIONS] SD ON S.SURVEYDEFINITIONID=SD.SURVEYDEFINITIONID
INNER JOIN [DBO].[PARENTCHILDS] PC ON SD.SURVEYDEFINITIONTYPEID=PC.CHILDID
INNER JOIN [DBO].[MASTERQUESTIONS] M ON SR.MASTERQUESTIONID=M.MASTERQUESTIONID
INNER JOIN [DBO].[QUESTIONGROUPS] Q ON M.QUESTIONGROUPID=Q.QUESTIONGROUPID
--WHERE (U.PARENTUSERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = (SELECT PARENTUSERID FROM USERS WHERE USERS.USERID= (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=#USERIDENTIFICATION))) OR
--U.PARENTUSERID = (SELECT PARENTUSERID FROM USERS WHERE USERS.USERID= (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=#USERIDENTIFICATION))) AND
WHERE ((U.USERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID =#COMPANYID))
OR U.USERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID=#COMPANYID))) AND
U.USERTYPEID = 3 AND (PC.PARENTID=#CASETYPEID OR PC.CHILDID=#CASETYPEID)
AND (1=CASE WHEN ((#GROUPTYPE= '-1') OR (Q.QUESTIONGROUPID=#GROUPTYPE)) THEN 1 ELSE 0 END)
AND SR.RESPONSEVALUE != -2147483648 AND S.SURVEYSTATUSID IN(6) AND S.SURVEYSTATUSID != 99
AND CAST(S.RESPONSEDATE AS DATE) BETWEEN #BEGINDATE AND #ENDDATE
/*INSERT VALUES IN TEMPALLUSER TABLE*/
INSERT INTO #TEMPALLUSER
SELECT U.USERID,U.NAME1,#QUARTERNAME,ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2),#ALLAVG FROM SURVEYRESPONSES SR LEFT OUTER JOIN SURVEYS S
ON SR.SURVEYID = S.SURVEYID
LEFT OUTER JOIN SURVEYTARGETS ST ON S.SURVEYTARGETID = ST.SURVEYTARGETID
LEFT OUTER JOIN USERS U ON ST.IDENTIFICATION = U.USERID
INNER JOIN [DBO].[SURVEYDEFINITIONS] SD ON S.SURVEYDEFINITIONID=SD.SURVEYDEFINITIONID
INNER JOIN [DBO].[PARENTCHILDS] PC ON SD.SURVEYDEFINITIONTYPEID=PC.CHILDID
INNER JOIN [DBO].[MASTERQUESTIONS] M ON SR.MASTERQUESTIONID=M.MASTERQUESTIONID
INNER JOIN [DBO].[QUESTIONGROUPS] Q ON M.QUESTIONGROUPID=Q.QUESTIONGROUPID
--WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=#USERIDENTIFICATION))
WHERE((U.USERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID =#COMPANYID))
OR U.USERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID=#COMPANYID)))
AND (PC.PARENTID=#CASETYPEID OR PC.CHILDID=#CASETYPEID)
AND (1=CASE WHEN ((#GROUPTYPE= '-1') OR (Q.QUESTIONGROUPID=#GROUPTYPE)) THEN 1 ELSE 0 END)
AND SR.RESPONSEVALUE != -2147483648 AND S.SURVEYSTATUSID IN(6) AND S.SURVEYSTATUSID != 99
AND CAST(S.RESPONSEDATE AS DATE) BETWEEN #BEGINDATE AND #ENDDATE
GROUP BY U.USERID, U.NAME1
ORDER BY ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2) DESC
SELECT #COUNT = COUNT(*) FROM #TEMPALLUSER
IF #COUNT = 0
BEGIN
INSERT INTO #TEMPALLUSER VALUES(NULL,'',#QUARTERNAME,0.0,0.0)
END
END /*END OF IF ELSE LOOP*/
SET #COUNTERCOUNT = #COUNTERCOUNT + 1
SET #BEGINDATE = '1900-01-01'
SET #ENDDATE = '1900-01-01'
END /*END WHILE LOOP */
/*FETCH DATA FROM TEMP TABLE*/
DECLARE #COLS AS NVARCHAR(MAX),
#QUERY AS NVARCHAR(MAX);
SELECT #COLS = STUFF((SELECT DISTINCT ',' + QUOTENAME(T.QUARTER)
FROM #TEMPUSER T
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #QUERY = 'SELECT DISTINCT USERID,USERNAME,AVGALL, ' + #COLS + ' FROM
(
SELECT DISTINCT T.USERID
, T.USERNAME
,T.AVGALL
, T.QUARTER
, T.AVG
FROM #TEMPUSER T
) X
PIVOT
(
MIN(AVG)
FOR QUARTER IN (' + #COLS + ')
) P '
EXECUTE(#QUERY)
DROP TABLE #TEMPUSER
END
GO
In this image same username/userid rahul has avg in different quarters like in q1-14 and so on.. but in row 1 it has avg in q1-14, after that in row 2 avg is q2-14 and so on.. but i want remove null column and merge row 1/2/3 that has same user name but avg in different row, so i want it on single row.
so i want like this as below image:

You could just GROUP and SUM the rows of the resulting table:
SELECT USERID, USERNAME, MIN(AVGALL) as AVGALL,
SUM(Q1-14) as Q114, SUM(Q2-14) as Q214, SUNM(Q4-13) as Q413
FROM [TABLE]
GROUP BY USERID, USERNAME
To use with your query, you could push the results into a temp table. Just replace your call to EXECUTE(#QUERY) with the below:
-- select your results in to a temp table
SELECT INTO #T1 execute ('execute ' + #QUERY)
-- Perform the group and sum operations on the temp table to output results
SELECT USERID, USERNAME, MIN(AVGALL) as AVGALL,
SUM(Q1-14) as Q114, SUM(Q2-14) as Q214, SUNM(Q4-13) as Q413
FROM [#T1]
GROUP BY USERID, USERNAME

Related

SQL query filling up tempdb

I am running the below query which is failing when it fills up the tempdb (170GB). It fails after around 1 hour.
the script below :
--Select Query BOM collection retail report
Declare #Company Nvarchar(50) ='HMFI'
Declare #Product Nvarchar(50) =Null
select Upper (Be.DataAreaId)Company ,BE.BOM,BE.Product
,Max(ProItemName)ProItemName
,Max(ProUnitID)ProUnitID
,Be.Material,Max(MaterialItemName)MaterialItemName
,Be.UNITID MaterialUnitID
,Sum (Be.BOMQTY)MaterialQty
,Max (MaterialService) MaterialType
from ExpBom_HMFI BE
Outer Apply (SELECT UNITID ProUnitID FROM INVENTTABLEMODULE A With (Nolock) WHERE DATAAREAID = #Company AND A.ITEMID =BE.Product AND MODULETYPE = 0)ProUnitID
Outer Apply(SELECT ITEMNAME ProItemName FROM INVENTTABLE B With (Nolock) WHERE DATAAREAID = #Company AND B.ITEMID = BE.Product)ProItemName
Outer Apply(SELECT ITEMNAME MaterialItemName FROM INVENTTABLE C With (Nolock) WHERE DATAAREAID = #Company AND C.ITEMID = Be.Material)MaterialItemName
Outer Apply(SELECT Case When ITEMTYPE=0 Then 'Item' When ITEMTYPE=1 Then 'BOM' When ITEMTYPE=2 Then 'Service Item' End MaterialService
FROM INVENTTABLE With (Nolock) WHERE DATAAREAID = #Company AND ITEMID = Be.Material)MaterialService
Where BE.DataAreaId in (#Company) and (#Product Is null Or Be.Product In(Select StringValue From Split(#Product,',')))
Group by Be.DataAreaId,BE.BOM,BE.Product,Be.Material ,Be.UNITID
Order By Be.DataAreaId,BE.BOM,BE.Product,Be.Material
option (maxrecursion 0)
--now Viewing the data collected
with ExpBom (
DataAreaId,
Bom,
Product,
Material,
BomDepth,
BOMQTY,
Unitid,
BomPath
) as (
select
bv.DataAreaId,
bv.BomId,
bv.ItemId,
b.ItemId,
1,
Convert (NUMERIC(18,8), b.BOMQTY) BOMQTY,
Convert (Nvarchar(10),b.UNITID )Unitid,
convert(Nvarchar(max), bv.ItemId + '|' + b.ItemId) as BomPath
from BomVersion bv With (Nolock)
join InventTable ibv With (Nolock)
on ibv.DataAreaId = bv.DataAreaId
and ibv.ItemId = bv.ItemId
join Bom b With (Nolock)
on b.DataAreaId = bv.DataAreaId
and b.BomId = bv.BomId
join InventTable ib With (Nolock)
on ib.DataAreaId = b.DataAreaId
and ib.ItemId = b.ItemId
where bv.Approved = 1
and bv.Active = 1
and bv.FromDate < getdate()
and (bv.ToDate = '01-01-1900' or bv.ToDate >= getdate())
and b.FromDate < getdate()
and (b.ToDate = '01-01-1900' or b.ToDate >= getdate())
and b.DATAAREAID in ('HMFI')
union all
select
bv.DataAreaId,
bv.BomId,
bv.ItemId,
eb.Material,
eb.BomDepth + 1,
Convert (NUMERIC(18,8),B.BOMQTY * eb.BOMQTY)BOMQTY,
Convert (Nvarchar(10),eb.UNITID )Unitid,
convert(Nvarchar(max), bv.ItemId + '|' + eb.BomPath) as BomPath
from BomVersion bv With (Nolock)
join InventTable ibv With (Nolock)
on ibv.DataAreaId = bv.DataAreaId
and ibv.ItemId = bv.ItemId
join Bom b With (Nolock)
on b.DataAreaId = bv.DataAreaId
and b.BomId = bv.BomId
join ExpBom eb
on eb.DataAreaId = b.DataAreaId
and eb.Product = b.ItemId
where bv.Approved = 1
and bv.Active = 1
and bv.FromDate < getdate()
and (bv.ToDate = '01-01-1900' or bv.ToDate >= getdate())
and b.FromDate < getdate()
and (b.ToDate = '01-01-1900' or b.ToDate >= getdate())
and b.DATAAREAID in ('HMFI')
)
select * from ExpBOM
Where Material Not in (Select BOMV.ITEMID From BomVersion BOMV With (Nolock) Where BOMV.DataAreaId In( 'HMFI' ) and BOMV.Approved = 1
and BOMV.Active = 1
and BOMV.FromDate < getdate()
and (BOMV.ToDate = '01-01-1900' or BOMV.ToDate >= getdate()) )
I'm not sure if the JOINS are causing the issue
Estimated execution plan is below:
Data collection :
https://www.brentozar.com/pastetheplan/?id=S1UsXn4Po
Data view:
https://www.brentozar.com/pastetheplan/?id=BJDUBn4wi
Please advise
this report was working fine on daily basis without filling tempdb usualy it was taking 1 min to execute suddenly it stoped for unknown reason although there's no changes done on server/database levels

How to execute 2 SQL statements inside a CASE

I have the following SQL query statement:
INSERT INTO #mt_API
SELECT
[dbo].fn_AddTimeZoneOffset(APHIST.ActionDate,'CET') AS ASDATE
, [dbo].fn_AddTimeZoneOffset(APHIST.ReturnDate,'CET') AS ATDATE
,API_HIST.[ActionPlanItemID]
,API_HIST.[ActionPlanID]
,PIT.[ProductItemID]
,PIT.ProductItemCode
,PIT.QRCode
,PIT.Name
,ISNULL((SELECT TOP 1 mRSP.TotalRemainingAtStore FROM #mt_RemainingStockProduct AS mRSP
WHERE mRSP.InventoryDate <= APHIST.ReturnDate
ORDER BY mRSP.InventoryDate DESC), 0) AS StoreTotalStock
,P.[Weight] AS ItemWeight
,M.UnitMeasureCode as Unit
,PIT.Quantity AS ItemQuantity
,P.ItemUnitWeight
,P.Quantity as ProductQuantity
,E1.FullName AS Emp1
,E2.FullName AS Emp2
,E3.FullName AS Emp3
,E4.FullName AS Emp4
,SECT.Name AS Sector
,CASE WHEN n=0 then 0 else [ItemStatus] end as [ItemStatus]
,APHIST.IsActionOver as ActionOver
FROM
[Sales].[ActionPlanItem_History] AS API_HIST
INNER JOIN
[Sales].[ActionPlan_History] AS APHIST On APHIST.ActionPlanID = API_HIST.ActionPlanID
INNER JOIN
[Production].[ProductItem] AS PIT ON API_HIST.ProductItemID =PIT.ProductItemID
INNER JOIN
Production.Product as P ON PIT.ProductID = P.ProductID AND PIT.ProductID = P.ProductID AND
PIT.ProductID = P.ProductID
INNER JOIN
Production.UnitMeasure as M ON M.UnitMeasureID = P.WeightUnitMeasureID
LEFT OUTER JOIN
Sales.Employee AS E1 ON APHIST.EmployeeID1 = E1.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E2 ON APHIST.EmployeeID2 = E2.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E3 ON APHIST.EmployeeID3 = E3.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E4 ON APHIST.EmployeeID4 = E4.EmployeeID
INNER JOIN
Sales.Sector AS SECT ON APHIST.SectorID = SECT.SectorID
INNER JOIN
Production.ProductSubcategory as PS on P.ProductSubcategoryID=PS.ProductSubcategoryID
INNER JOIN
Production.ProductCategory as PC on PS.ProductCategoryID= PC.ProductCategoryID
CROSS APPLY (Values(0),(1)) d(n)
WHERE P.StoreID=#StoreID
--WHERE PC.ProductCategoryID=#RootCategory AND P.StoreID=#StoreID
--ORDER BY ProductItemCode, ATDATE
ORDER BY ASDATE , ProductItemCode
SELECT
API1.ASDATE AS StartDate
,API1.ATDATE AS ReturnDate
,API1.ActionPlanItemID
,API1.ActionPlanID
,API1.ProductItemID
,API1.ProductItemCode
,API1.QRCode
,API1.Name
,API1.StoreTotalStock
,API1.ItemWeight
,API1.ItemQuantity
,API1.ItemUnitWeight
,API1.Unit
,API1.ProductQuantity
,API1.Emp1
,API1.Emp2
,API1.Emp3
,API1.Emp4
,API1.Sector
,API1.ItemStatus
,API1.ActionOver
,(API1.StoreTotalStock +
(SELECT SUM(
CASE API2.ItemStatus
WHEN 0 THEN -1
WHEN 1 THEN 1
ELSE 0
END * API2.ItemUnitWeight)
FROM #mt_API AS API2
WHERE API2.ID <= API1.ID
)
-
(
**select
case ISNULL(SUM([ProductItemWeight]), 0)
when 0 then 0
else SUM([ProductItemWeight])
end
from [ExplosiveTracking].[Production].[TransfertHistory]
where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')**
)
) AS ItemWeightBal
FROM #mt_API AS API1
Inside the CASE statement I am returning the SUM([ProductItemWeight]) if it is not NULL, but then at same time, I need to execute the following inside the same CASE :
delete from #tempTransfert
where stuff(convert(varchar(20),#tempTransfert.TransferDate,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')
ADDED MORE TEST :
If I run what I wan to accomplish in a standalone new query as below then the DELETE and SELECT works find inside the CASE
CREATE TABLE #tempTransfert
(
[ID] uniqueidentifier,
[ProductId] int,
[SourceId] int,
TransferDate DateTime,
TotalMovedProduct DECIMAL(16,4)
)
Insert into #tempTransfert
select
[ID],[ProductId], [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') as TransferDate, SUM([ProductItemWeight]) as TotalMovedProduct
from [ExplosiveTracking].[Production].[TransfertHistory]
group by [ProductId],ID, [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'')
select * from #tempTransfert
MERGE #tempTransfert AS T
USING (select
case ISNULL(SUM([ProductItemWeight]) , 0)
when 0 then 0
else SUM([ProductItemWeight])
end
, ID
from [ExplosiveTracking].[Production].[TransfertHistory]
where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),'2017-02-28 15:38:00',120),17,6,'')
Group by ID
) as S ([ProductItemWeight],ID)
ON (T.ID = S.ID)
WHEN MATCHED
THEN DELETE;
BUT when I added in the complete query as below , I have a SYNTAX error near MERGE reported :
DECLARE #m_StoreTotalStock AS DECIMAL(18,3)
DECLARE #mt_API AS TABLE
(
ID INT IDENTITY(1,1), ASDATE DATETIME,ATDATE DATETIME,
ActionPlanItemID INT, ActionPlanID INT,
ProductItemID INT, ProductItemCode VARCHAR(50),
QRCode VARCHAR(50), Name VARCHAR(50),
StoreTotalStock decimal(18,3), ItemWeight decimal(18,3),
Unit VARCHAR(50), ItemQuantity INT,
ItemUnitWeight DECIMAL(18,4), ProductQuantity INT,
Emp1 VARCHAR(50), Emp2 VARCHAR(50),
Emp3 VARCHAR(50), Emp4 VARCHAR(50),
Sector VARCHAR(50), ItemStatus TINYINT,ActionOver INt
)
DECLARE #mt_RemainingStockProduct AS TABLE
(
StoreID INT,InventoryDate DATETIME,ProductID INT, TotalRemainingAtStore DECIMAL(18,2)
)
CREATE TABLE #tempTransfert
(
[ID] uniqueidentifier,
[ProductId] int,
[SourceId] int,
TransferDate DateTime,
TotalMovedProduct DECIMAL(16,4)
)
Insert into #tempTransfert
select
[ID],[ProductId], [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') as TransferDate, SUM([ProductItemWeight]) as TotalMovedProduct
from [ExplosiveTracking].[Production].[TransfertHistory]
group by [ProductId],ID, [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'')
select * from #tempTransfert
/** Get Remaining StockBy Product **/
INSERT INTO #mt_RemainingStockProduct
(
StoreID, InventoryDate, ProductID,TotalRemainingAtStore
)
--SELECT InventoryDate, SUM(TotalRemainingAtStore) AS TotalRemainingAtStore FROM
--(
SELECT StoreID, InventoryDate, ProductID, SUM(Remaining) OVER (PARTITION BY StoreID ) AS TotalRemainingAtStore FROM
(
SELECT
P.StoreID, P.InventoryDate, P.ProductID,
--SUM(PIT.Quantity * P.ItemUnitWeight)-SUM(PIT.UsedQuantity * P.ItemUnitWeight) AS Remaining
SUM(PIT.Quantity * P.ItemUnitWeight) AS Remaining
FROM Sales.Store AS S
INNER JOIN Production.ProductItem AS PIT
INNER JOIN Production.Product AS P ON PIT.ProductID = P.ProductID
INNER JOIN Production.UnitMeasure AS UM ON P.WeightUnitMeasureID = UM.UnitMeasureID ON
S.BusinessEntityID = P.StoreID
INNER JOIN Production.Location AS LOC ON S.BusinessEntityID = LOC.StoreID AND
P.LocationID = LOC.LocationID AND P.LocationID = LOC.LocationID
WHERE (P.IsDeleted = 0) AND (PIT.IsDeleted = 0) AND P.StoreID = 4
GROUP BY P.StoreID,P.InventoryDate, P.ProductID, UM.UnitMeasureCode, S.Name, LOC.MaxQuantity
) AS RST1
--) AS RST2
--GROUP BY RST2.InventoryDate
/** Endof Get Remaining StockBy Product **/
-- Get Store total product items weight
SELECT #m_StoreTotalStock = SUM(PIW.TotalWeight)
FROM dbo.v_ProductItemWeight AS PIW
WHERE StoreID = 4
INSERT INTO #mt_API
SELECT [dbo].fn_AddTimeZoneOffset(APHIST.ActionDate,'CET') AS ASDATE
, [dbo].fn_AddTimeZoneOffset(APHIST.ReturnDate,'CET') AS ATDATE
,API_HIST.[ActionPlanItemID]
,API_HIST.[ActionPlanID]
,PIT.[ProductItemID]
,PIT.ProductItemCode
,PIT.QRCode
,PIT.Name
,ISNULL((SELECT TOP 1 mRSP.TotalRemainingAtStore FROM #mt_RemainingStockProduct AS mRSP
WHERE mRSP.InventoryDate <= APHIST.ReturnDate
ORDER BY mRSP.InventoryDate DESC), 0) AS StoreTotalStock
,P.[Weight] AS ItemWeight
,M.UnitMeasureCode as Unit
,PIT.Quantity AS ItemQuantity
,P.ItemUnitWeight
,P.Quantity as ProductQuantity
,E1.FullName AS Emp1
,E2.FullName AS Emp2
,E3.FullName AS Emp3
,E4.FullName AS Emp4
,SECT.Name AS Sector
,CASE WHEN n=0 then 0 else [ItemStatus] end as [ItemStatus]
,APHIST.IsActionOver as ActionOver
FROM
[Sales].[ActionPlanItem_History] AS API_HIST
INNER JOIN
[Sales].[ActionPlan_History] AS APHIST On APHIST.ActionPlanID = API_HIST.ActionPlanID
INNER JOIN
[Production].[ProductItem] AS PIT ON API_HIST.ProductItemID =PIT.ProductItemID
INNER JOIN
Production.Product as P ON PIT.ProductID = P.ProductID AND PIT.ProductID = P.ProductID AND
PIT.ProductID = P.ProductID
INNER JOIN
Production.UnitMeasure as M ON M.UnitMeasureID = P.WeightUnitMeasureID
LEFT OUTER JOIN
Sales.Employee AS E1 ON APHIST.EmployeeID1 = E1.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E2 ON APHIST.EmployeeID2 = E2.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E3 ON APHIST.EmployeeID3 = E3.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E4 ON APHIST.EmployeeID4 = E4.EmployeeID
INNER JOIN
Sales.Sector AS SECT ON APHIST.SectorID = SECT.SectorID
INNER JOIN
Production.ProductSubcategory as PS on P.ProductSubcategoryID=PS.ProductSubcategoryID
INNER JOIN
Production.ProductCategory as PC on PS.ProductCategoryID= PC.ProductCategoryID
CROSS APPLY (Values(0),(1)) d(n)
WHERE P.StoreID=4
--WHERE PC.ProductCategoryID=#RootCategory AND P.StoreID=#StoreID
--ORDER BY ProductItemCode, ATDATE
ORDER BY ASDATE , ProductItemCode
SELECT
API1.ASDATE AS StartDate
,API1.ATDATE AS ReturnDate
,API1.ActionPlanItemID
,API1.ActionPlanID
,API1.ProductItemID
,API1.ProductItemCode
,API1.QRCode
,API1.Name
,API1.StoreTotalStock
,API1.ItemWeight
,API1.ItemQuantity
,API1.ItemUnitWeight
,API1.Unit
,API1.ProductQuantity
,API1.Emp1
,API1.Emp2
,API1.Emp3
,API1.Emp4
,API1.Sector
,API1.ItemStatus
,API1.ActionOver
,(API1.StoreTotalStock +
(SELECT SUM(
CASE API2.ItemStatus
WHEN 0 THEN -1
WHEN 1 THEN 1
ELSE 0
END * API2.ItemUnitWeight)
FROM #mt_API AS API2
WHERE API2.ID <= API1.ID
)
-
--select
-- case ISNULL(SUM([ProductItemWeight]), 0)
-- when 0 then 0
-- else SUM([ProductItemWeight])
-- end
--from [ExplosiveTracking].[Production].[TransfertHistory]
--where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')
(
**MERGE #tempTransfert AS T
USING (select
case ISNULL(SUM([ProductItemWeight]) , 0)
when 0 then 0
else SUM([ProductItemWeight])
end
, ID
from [ExplosiveTracking].[Production].[TransfertHistory]
where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')
Group by ID
) as S ([ProductItemWeight],ID)
ON (T.ID = S.ID)
WHEN MATCHED
THEN DELETE;
)**
) AS ItemWeightBal
FROM #mt_API AS API1
END
The MERGE part is suppose to first return the SUM of ItemWeight within a DateTime range, then when those records has been read, I need to delete them from #tempTransfert table otherwise, on the next loop it will read all records again
Any idea what syntax error can it be ?
Thanks for your help on this
Regards

Stored procedure taking long time when it runs through SSIS package

I have a below procedure which uses 3 temp tables and finally insert into a table. I am using below sp as source (execute sql task) and loading into csv files. When i run this sp from SSMS it runs within 10 seconds, but when I Put into SSIS package it runs for 30 mins and keep on running. Could any of you optimize this SP for SSIS package?
create proc [etl].[payment_report]
#start_date datetime,
#end_date datetime
as
begin
truncate table extract.payment
select
a.bb_acct_id, a.customer_id,
pay.order_id Payment_Order_Id,
aoi.ord_prod_id Ord_Prod_Id,
pd.name, pd.quick_cd
into
#IntialOrders
from
(select *
from stg.payment (NOLOCK)
where order_id is not null) pay
inner join
stg.account a (NOLOCK) on pay.acct_id = a.acct_id
inner join
stg.acct_order ao (NOLOCK) on ao.order_id = pay.order_id
inner join
stg.acct_order_item aoi (NOLOCK) on aoi.order_id = ao.order_id
inner join
stg.ordered_product op (NOLOCK) on op.ord_prod_id = aoi.ord_prod_id
left join
stg.product p (NOLOCK) on p.prod_id = op.prod_id
left join
stg.product_def pd (NOLOCK) on pd.prod_def_id = p.prod_def_id
where
pay.received_date >= #start_date
and pay.received_date < #end_date
and pay.payment_id not in (select payment_id
from stg.op_renewal_history)
create clustered index Idx_Payment_Order_Id on #IntialOrders(Payment_Order_Id)
select
pay.payment_id, gwr.response
into
#gateway_response
from
stg.payment pay (NOLOCK)
inner join
stg.cc_transactions cct (NOLOCK) on cct.payment_id = pay.payment_id
inner join
stg.gateway_response gwr (NOLOCK) on cct.c_c_trans_id = gwr.cc_trans_id
where
pay.posting_status_id = 3
and pay.received_date >= #start_date
and pay.received_date < #end_date
and pay.received_date > '2015-04-15 00:00:00'
select
distinct a.bb_acct_id SP_ACCOUNT_ID
,a.customer_id CP_CUSTOMER_ID
,bu.description BUSINESS_UNIT
,pay.payment_id PAYMENT_ID
,pay.payment_amt AMOUNT
,'SEK' CURRENCY
,Substring(convert(char(19),pay.received_date,126), 1, (len(convert(char(19),pay.received_date,126))-0))+'Z' PAYMENT_DATE
,pt.display_name PAYMENT_METHOD
,post.description PAYMENT_STATUS
,pay.retries PAYMENT_RETRIES
,case when (pay.for_bill_id is not null or orh.op_id is not null) then 'Renewal' else 'OneTime' end as PAYMENT_TYPE
,case when pay.posting_status_id =3 then gwr.response else '' end as FAILURE_REASON
,case when op.ord_prod_id is null then ino.name else pd.name end SUBSCRIPTION_NAME
,case when op.ord_prod_id is null then ino.quick_cd else pd.quick_cd end SKU
,case when op.ord_prod_id is null then ino.Ord_Prod_Id else op.ord_prod_id end ORD_PROD_ID
,convert(char(19),GETDATE(),126)+'Z' EXPORT_TIME
,case when (pay.posting_status_id =3 and pay.retries = 3 ) then 'T' else 'F' end FAILED_EXTENDED_RETRY
into #payment
from stg.payment pay (NOLOCK)
left join #IntialOrders ino (NOLOCK) on
ino.Payment_Order_Id=pay.order_id
left join stg.account a (NOLOCK) on
a.acct_id = pay.acct_id
left join stg.business_unit bu (NOLOCK) on
a.bu_id=bu.bu_id
left join stg.payment_method pm (NOLOCK) on
pm.pay_method_id=pay.payment_method_id
left join stg.payment_type pt (NOLOCK) on
pt.id=pm.type_id
left join stg.posting_status post (NOLOCK) on
post.id=pay.posting_status_id
left join stg.op_renewal_history orh (NOLOCK) on
orh.payment_id = pay.payment_id
left join stg.ordered_product op (NOLOCK) on
op.ord_prod_id = orh.op_id
left join stg.product p (NOLOCK) on
p.prod_id = op.prod_id
left join stg.product_def pd (NOLOCK) on
pd.prod_def_id = p.prod_def_id
left join #gateway_reponse gwr (NOLOCK) on
gwr.payment_id = pay.payment_id
where
a.bu_id=1
and (a.acct_role_id is null or a.acct_role_id !=4)
and (pay.posting_status_id=2 or (pay.posting_status_id =3
and pay.retries = 3
and op.acct_status_id=3))
and pay.received_date >=#start_date
and pay.received_date < #end_date
and pay.received_date > '2015-04-15 00:00:00'
insert into extract.payment
(
SP_ACCOUNT_ID
,CP_CUSTOMER_ID
,BUSINESS_UNIT
,PAYMENT_ID
,AMOUNT
,CURRENCY
,PAYMENT_DATE
,PAYMENT_METHOD
,PAYMENT_STATUS
,PAYMENT_RETRIES
,PAYMENT_TYPE
,FAILURE_REASON
,SUBSCRIPTION_NAME
,SKU,ORD_PROD_ID
,EXPORT_TIME
,FAILED_EXTENDED_RETRY
)
select
cast(p.SP_ACCOUNT_ID as varchar(50)) SP_ACCOUNT_ID
,cast(p.CP_CUSTOMER_ID as varchar(50)) CP_CUSTOMER_ID
,cast(p.BUSINESS_UNIT as varchar(500)) BUSINESS_UNIT
,cast( p.PAYMENT_ID as varchar(50)) PAYMENT_ID, p.AMOUNT
,cast( p.CURRENCY as varchar(50)) CURRENCY
,cast( p.PAYMENT_DATE as varchar(50)) PAYMENT_DATE
,cast( p.PAYMENT_METHOD as varchar(50)) PAYMENT_METHOD
,cast(p.PAYMENT_STATUS as varchar(50)) PAYMENT_STATUS
,cast( p.PAYMENT_RETRIES as varchar(50)) PAYMENT_RETRIES
,cast(p.PAYMENT_TYPE as varchar(50)) PAYMENT_TYPE
,cast( p.FAILURE_REASON as varchar(4000)) FAILURE_REASON
,cast(p.SUBSCRIPTION_NAME as varchar(500)) SUBSCRIPTION_NAME
,cast(p.SKU as varchar(50)) SKU
,cast(p.ORD_PROD_ID as varchar(50)) ORD_PROD_ID
,cast( p.EXPORT_TIME as varchar(50)) EXPORT_TIME
,p.FAILED_EXTENDED_RETRY
from #payment p
order by p.PAYMENT_DATE
Drop table #IntialOrders
Drop table #gateway_reponse
Drop table #payment
END

Way of adding a total row to the bottom of a SQL query

I've got a web based report pulling out a load of information from our SQL server and wanted to know the best way of adding a "totals" row to the bottom. The query is full of subqueries, so I'm not sure of the best way of adding a summary row on the bottom.
I know the "best" way would be to do this in the presentation layer, but I've got sweet FA knowledge of the presentation layer (as the chap that made it has since left and no-one has the same skill set...!)
SELECT
dbo.Groups.GroupName, dbo.UserGroups.GroupId, dbo.Users.UserName + ' ' + dbo.Users.Surname AS Consultant,
dbo.UserGroups.UserId,
(SELECT COUNT(*) AS ManagerCount
FROM dbo.ClientContacts
WHERE (CreatedUserId = dbo.Users.UserId) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS ManagersAdded,
(SELECT COUNT(*) AS InterviewCount
FROM dbo.Interviews
WHERE (CreatedUserId = dbo.Users.UserId) AND (InterviewTypeId = 1) AND (Createdon BETWEEN #startDate AND #endDate)) AS FirstInterviewCount,
(SELECT COUNT(*) AS InterviewCount
FROM dbo.Interviews AS Interviews_1
WHERE (CreatedUserId = dbo.Users.UserId) AND (InterviewTypeId in (1,3,4)) AND (Createdon BETWEEN #startDate AND #endDate)) AS InterviewCount,
(SELECT COUNT(*) AS InterviewCount
FROM dbo.Interviews AS Interviews_1
WHERE (CreatedUserId = dbo.Users.UserId) AND (InterviewTypeId in (2)) AND (Createdon BETWEEN #startDate AND #endDate)) AS TelephoneCount,
(SELECT COUNT(*) AS DMSpokenTo
FROM dbo.NotebookItems
WHERE (CreatedUserId = dbo.Users.UserId) AND (NotebookTypeId = 56) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS DMSpokenTo,
(SELECT COUNT(*) AS Appspokento
FROM dbo.NotebookItems
WHERE (CreatedUserId = dbo.Users.UserId) AND (NotebookTypeId = 85) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS AppSpokenTo,
(SELECT COUNT(*) AS Marketed
FROM dbo.NotebookItems AS NotebookItems_1
WHERE (CreatedUserId = dbo.Users.UserId) AND (NotebookTypeId = 124) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS Marketed,
(SELECT COUNT(*) AS CVSent
FROM dbo.ApplicantActions
WHERE (CreatedUserId = dbo.Users.UserId) AND (StatusId <> 28) AND (JobId IS NOT NULL) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS CVSent,
(SELECT COUNT(*) AS CVSent
FROM dbo.ApplicantActions
WHERE (CreatedUserId = dbo.Users.UserId) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS Speccv,
(SELECT COUNT(*) AS Meetings
FROM dbo.DiaryEvents
WHERE (CreatedUserId = dbo.Users.UserId) AND (EventTypeID = 29) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS Meetings,
(SELECT COUNT(*) AS VacanciesAdded
FROM dbo.Jobs
WHERE (CreatedUserId = dbo.Users.UserId) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS VacanciesAdded,
(SELECT SUM(pc.CommissionPerc / 100) AS PermPlacements
FROM dbo.Placements
INNER JOIN PlacementConsultants pc on placements.PlacementID = pc.PlacementId
INNER JOIN PlacementSectorDefinedColumns psdc on psdc.PlacementId = placements.PlacementID
WHERE (isnull(psdc.notnewbusiness,'N') = 'N') AND (pc.UserId = dbo.Users.UserId) AND (placements.CreatedOn BETWEEN #startDate AND #endDate) AND (PlacementTypeId <> 6)) AS [Perm Placements],
(SELECT SUM(PlacementFee / 100 * pc.CommissionPerc) AS PermFee
FROM dbo.Placements
INNER JOIN PlacementConsultants pc on placements.PlacementID = pc.PlacementId
INNER JOIN PlacementSectorDefinedColumns psdc on psdc.PlacementId = placements.PlacementID
WHERE (isnull(psdc.notnewbusiness,'N') = 'N') AND (pc.UserId = dbo.Users.UserId) AND (placements.CreatedOn BETWEEN #startDate AND #endDate) AND (PlacementTypeId <> 6)) AS [Perm Fee],
(SELECT SUM(pc.CommissionPerc / 100) AS ContractPlacements
FROM dbo.Placements
INNER JOIN PlacementConsultants pc on placements.PlacementID = pc.PlacementId
INNER JOIN PlacementSectorDefinedColumns psdc on psdc.PlacementId = placements.PlacementID
WHERE (isnull(psdc.notnewbusiness,'N') = 'N') AND (pc.UserId = dbo.Users.UserId) AND (placements.CreatedOn BETWEEN #startDate AND #endDate) AND (PlacementTypeId = 6)) AS [Contract Placements],
(SELECT SUM(dbo.CONTRACT_NETT_VALUE_FOR_INITIAL_PLACEMENT(Placements_1.PlacementID) / 100 * pc.CommissionPerc) AS ContractFee
FROM dbo.Placements AS Placements_1
INNER JOIN PlacementConsultants pc on Placements_1.PlacementID = pc.PlacementId
INNER JOIN PlacementSectorDefinedColumns psdc on psdc.PlacementId = Placements_1.PlacementID
WHERE (isnull(psdc.notnewbusiness,'N') = 'N') AND (pc.UserId = dbo.Users.UserId) AND (Placements_1.CreatedOn BETWEEN #startDate AND #endDate) AND (PlacementTypeId = 6)) AS [Contract Value]
FROM dbo.Groups INNER JOIN
dbo.UserGroups ON dbo.Groups.GroupId = dbo.UserGroups.GroupId INNER JOIN
dbo.Users ON dbo.UserGroups.UserId = dbo.Users.UserId
WHERE (
(dbo.Users.Inactive = 'N') AND (dbo.UserGroups.GroupId = #GroupId) )
and users.userid not in (select userid from UserGroups where GroupId = 57)
One approach could be to do a UNION and then add in another set of subqueries, but that's going to get really messy and ridiculously long winded surely?
Is there a better way of doing it than that?
Try ROLLUP.
For performance reasons, I would consider using table variables or temp tables to avoid multiple queries of the same tables. Also, table variables and temp tables can have at least a primary key, whereas common table expressions are not indexed.
For example:
DECLARE #GroupName VARCHAR(100)
SELECT #GroupName = g.GroupName
FROM dbo.Groups g
WHERE g.GroupId = #GroupId
DECLARE #Users TABLE
(
UserId INT NOT NULL PRIMARY KEY,
Consultant VARCHAR(100) NOT NULL
)
INSERT #Users (UserId, Consultant)
SELECT u.UserId, u.UserName + ' ' + u.Surname
FROM dbo.Users u
INNER JOIN dbo.UserGroups ug ON u.UserId = ug.UserId AND ug.GroupId = #GroupId
WHERE u.Inactive = 'N'
AND NOT EXISTS (SELECT 1 FROM dbo.UserGroups ne
WHERE u.UserId = ne.UserId
AND ne.GroupId = 57)
DECLARE #ClientContacts TABLE
(
UserId INT NOT NULL PRIMARY KEY,
ManagerCount INT NOT NULL
)
INSERT #ClientContacts (UserId, ManagerCount)
SELECT u.UserId, COUNT(*)
FROM #Users u
INNER JOIN dbo.ClientContacts cc ON cc.CreatedUserId = u.UserId AND cc.CreatedOn BETWEEN #startDate AND #endDate
GROUP BY u.UserId
DECLARE #Interviews TABLE
(
UserId INT NOT NULL,
InterviewTypeId INT NOT NULL,
InterviewCount INT NOT NULL,
PRIMARY KEY (UserId, InterviewTypeId)
)
INSERT #Interviews (UserId, InterviewTypeId, InterviewCount)
SELECT u.UserId, i.InterviewTypeId, COUNT(*)
FROM #Users u
INNER JOIN dbo.Interviews i ON u.UserId = i.CreatedUserId AND i.InterviewTypeId BETWEEN 1 AND 4 AND i.CreatedOn BETWEEN #StartDate AND #EndDate
GROUP BY u.UserId, i.InterviewTypeId
-- Rest is an exercise for the reader, but:
SELECT #GroupName AS GroupName,
#GroupId AS GroupId,
CASE GROUPING(u.UserId) WHEN 1 THEN NULL ELSE MIN(u.Consultant) END AS Consultant,
u.UserId,
SUM(COALESCE(cc.ManagerCount, 0)) AS ManagersAdded,
SUM(COALESCE(ip.[1], 0)) AS FirstInterviewCount,
SUM(COALESCE(ip.[1], 0) + COALESCE(ip.[3], 0) + COALESCE(ip.[4], 0)) AS InterviewCount,
SUM(COALESCE(ip.[2], 0)) AS TelephoneCount
FROM #Users u
LEFT JOIN #ClientContacts cc ON u.UserId = cc.UserId
LEFT JOIN (SELECT i.UserId, i.InterviewTypeId, i.InterviewCount
FROM #Interviews i) AS ii
PIVOT (SUM(InterviewCount) FOR InterviewTypeId IN ([1], [2], [3], [4])) AS ip ON u.UserId = ip.UserId
GROUP BY ROLLUP(u.UserId)
ORDER BY GROUPING(u.UserId), u.UserId

Need to insert a record if count = 0 else update the record

I need to write a query where i need to check the count record if count is 0, I am suppose to insert a record else update the record
If I do the same thing using cursor, it works fine but the same thing doesnt work with no cursor
Here is my query (with no cursor)
---Without cursor
INSERT INTO [dbo].Products_Del (product_Id, product_Del_startdate)
SELECT f.product_Id, min(cast(product_startdate as datetime)) AS orig_order_date FROM [dbo].Products f
inner join [dbo].Products_Del ac on f.product_Id = ac.product_Id
WHERE Product_Status = 'ORDERED'
AND product_startdate != '.'
AND (select COUNT(*) FROM products f1
INNER JOIN dbo.Products_Del ac on f1.product_Id = ac.product_Id
where f1.product_Id = f.product_Id) = 0
GROUP BY f.product_Id --order by product_Id
-- Update if exists
;with cts
AS (
SELECT product_Id , min(cast(product_startdate as datetime)) as orig_date from [dbo].Products f
WHERE product_Id in (select product_Id from Products_Del)
and Product_Status = 'ORDERED'
AND product_startdate != '.' -- ignore rows where date is unknown
AND (select COUNT(*) FROM Products f1
INNER JOIN dbo.Products_Del ac on f1.Product_id = ac.Product_id
where f1.product_Id = f.product_Id) = 1
GROUP BY product_Id
)
UPDATE ac
SET ac.product_Del_startdate = cts.orig_date
FROM Products_Del ac
INNER JOIN cts ON ac.product_Id = cts.product_Id
But this works good (with cursor)
DECLARE #v_count INT
DECLARE #c_product_id INT
DECLARE #c_product_date DATETIME
DECLARE cursor1 CURSOR FOR
SELECT product_id,
min(cast(product_startdate as DATETIME)) AS orig_order_date
FROM [dbo].Products
WHERE Product_Status = 'ORDERED'
AND product_startdate != '.' -- ignore rows where date is unknown
GROUP BY product_id
--order by product_id
OPEN cursor1
FETCH NEXT FROM cursor1 INTO #c_product_id,#c_product_date
WHILE(##FETCH_STATUS = 0)
BEGIN
SELECT #v_count = COUNT(*)
FROM [dbo].Products_Del
WHERE product_Id = #c_product_id
IF #v_count = 1
BEGIN
-- If so, plug the date into that row.
UPDATE [dbo].Products_Del
SET product_Del_startdate = #c_product_date
WHERE product_Id = #c_product_id
END
ELSE
BEGIN
-- If not, then create a new row in the aircraft_delivery_status table
IF #v_count = 0
BEGIN
INSERT INTO [dbo].Products_Del
(product_Id, product_Del_startdate)
VALUES (#c_product_id, #c_product_date)
END
END
FETCH NEXT FROM cursor1 INTO #c_product_id,#c_product_date
END
CLOSE cursor1
DEALLOCATE cursor1
SQL Fiddle link with schema
http://sqlfiddle.com/#!6/a7d0d/1
In the insert statement you have incorrect join
inner join [dbo].Products_Del ac on f.product_Id = ac.product_Id
just remove it
In the update statement (or ctp) you have incorrect condition :
(select COUNT(*) FROM Products f1
INNER JOIN dbo.Products_Del ac on f1.Product_id = ac.Product_id
where f1.product_Id = f.product_Id) =
1
because you have multiple rows with the same product_id in products table you can get more than one row in this subquery
Also I can suggest following query:
WITH OrderedProducts as(
SELECT p.product_id as product_id,
min(cast(product_startdate as datetime)) as start_date
FROM [dbo].[Products] as p
WHERE p.Product_Status = 'ORDERED'
AND p.Product_startdate != '.'
GROUP BY p.product_id
)
UPDATE pd
SET pd.product_Del_startdate = op.start_date
FROM Products_Del pd
INNER JOIN OrderedProducts as op ON pd.product_Id = op.product_Id
;WITH OrderedProducts as(
SELECT p.product_id as product_id,
min(cast(product_startdate as datetime)) as start_date
FROM [dbo].[Products] as p
WHERE p.Product_Status = 'ORDERED'
AND p.Product_startdate != '.'
GROUP BY p.product_id
)
INSERT INTO [dbo].Products_Del (product_Id, product_Del_startdate)
SELECT op.product_id, op.start_date FROM OrderedProducts as op
WHERE NOT EXISTS (
SELECT pd.product_id FROM [dbo].Products_Del as pd
WHERE pd.product_id = op.product_id )

Resources