SQL Pivot as a sub query - sql-server

I have the below code:
DECLARE #lcid INT
DECLARE #startdate DATETIME=#10
DECLARE #enddate DATETIME=#11
DECLARE #PitchJobTypeId INT
DECLARE #ClientInvestmentJobTypeId INT
DECLARE #AdministrationJobTypeId INT
IF OBJECT_ID('tempdb..#data') IS NOT NULL
DROP TABLE #data
DECLARE #Billablejob TABLE(
id INT IDENTITY(1,1),
Jobid INT)
DECLARE #Department table(
Id INT IDENTITY(1,1),
DepartmentId INT)
IF #10 > #11
BEGIN
SELECT 'Error in date selection' AS 'Error';
GOTO ExitSp;
END
INSERT INTO #Billablejob(Jobid)
SELECT distinct s.Element FROM dbo.Split(#30,',') AS s
Insert into #Department(DepartmentId)
SELECT distinct s.Element FROM dbo.Split(#5,',') AS s
IF EXISTS(SELECT '' FROM #Department AS d WHERE d.DepartmentId=0) OR NOT EXISTS(SELECT '' FROM #Department AS d) BEGIN
DELETE FROM #Department
INSERT INTO #Department(DepartmentId)
SELECT rsa.AfdID FROM RessSelAfd AS rsa --INNER JOIN #comp c ON c.compid=rsa.SelID
END
IF #20 IS NULL SET #20=0
CREATE TABLE #data(
ID INT IDENTITY(1,1),
[Name] nvarchar(MAX),
[Employee Type] nvarchar(MAX),
[Basic Time] money,
[Used Time] MONEY,
[Holiday] MONEY,
[Recovery] MONEY,
[Illness] MONEY,
[Billable Time] MONEY,
[Non Billable Time] MONEY,
[Pitch Time] MONEY,
[Internal Time] MONEY,
[Used Time2] MONEY,
[Max Billable Hours] MONEY,
[Available Hours] MONEY,
[Office Hours %] INT,
[Billable %] INT,
[Non Billable %] INT,
[Pitch %] INT,
[Internal %] INT,
[Billable Target %] INT,
[Variance to Target %] INT,
[Department] NVARCHAR(max),
[Job Role] NVARCHAR(max),
[Market] NVARCHAR(max),
EmpId INT,
DepartmentId INT,
JobRoleId INT,
MarketId INT,
IsActive BIT,
Hiredate DATETIME,
Expirydate DATETIME,
EmployeeType INT
)
IF #10>#11 BEGIN
SELECT 'Date selection error' Error
GOTO ExitSp
END
SELECT #PitchJobTypeId = sj.JobTypeID FROM SysJobtype AS sj WHERE sj.JobtypeNavn='Pitch'
IF #PitchJobTypeId IS NULL BEGIN
SELECT 'Jobtype ''Pitch'' not found' Error
GOTO ExitSp
END
SELECT #ClientInvestmentJobTypeId = sj.JobTypeID FROM SysJobtype AS sj WHERE sj.JobtypeNavn='Client Investment'
IF #ClientInvestmentJobTypeId IS NULL BEGIN
SELECT 'Jobtype ''Client Investment'' not found' Error
GOTO ExitSp
END
SELECT #AdministrationJobTypeId = sj.JobTypeID FROM SysJobtype AS sj WHERE sj.JobtypeNavn='Administration'
IF #AdministrationJobTypeId IS NULL BEGIN
SELECT 'Jobtype ''Administration'' not found' Error
GOTO ExitSp
END
SELECT #lcid=InterfaceLcid FROM ress WHERE ressid=#UserId
INSERT INTO #data( empid,[Name],[Billable Target %],[JobRoleId],[Job Role],DepartmentId,MarketId,IsActive,Hiredate,Expirydate,EmployeeType,[Employee Type])
SELECT emp.empid,EmpName,(SELECT TOP 1 ehp.ProfitTarget*100 FROM EmpHrsPrice AS ehp WHERE ehp.EmpId = emp.empid AND ehp.ValidFrom <= #enddate ORDER BY ehp.ValidFrom desc),emppost.PostId,
(SELECT ISNULL(nullif(ActLang.ActTxt,''), Act.ActTxt)
FROM Act
LEFT JOIN ActLang
ON Act.AID = ActLang.Aid
AND ActLang.LCID=#LCID
WHERE Act.AID=emp.aid),emp.DepartmentId,emp.CompId,emp.IsActive,emp.Hiredate,emp.Expirydate,emp.EmployTypeId,CASE WHEN et.enumval=1 OR et.enumval=2 THEN 'Permanent' ELSE 'Freelance' END FROM emp
INNER JOIN ress ON ress.RessID=emp.EmpId
INNER JOIN #Department AS d ON d.DepartmentId = Emp.DepartmentId
LEFT JOIN emppost ON emp.PostId=emppost.PostId
LEFT JOIN EnumTable(467) AS et ON et.EnumVal=emp.EmployTypeId
WHERE (IsActive=1 OR (Expirydate>=#startdate and Expirydate<=#enddate)) AND (CASE WHEN emp.EmployTypeId=2 THEN 1 ELSE emp.EmployTypeId END=#20 OR #20=0) AND Ress.UserAcountType<>5
UPDATE d SET d.Department=rsa.AfdNavn FROM #data d INNER JOIN RessSelAfd AS rsa ON d.DepartmentId=rsa.AfdID
UPDATE d SET d.Market=comp.CompName FROM #data d INNER JOIN comp ON d.MarketId=comp.compid
UPDATE d SET d.[Basic Time]=data.HrsNorm FROM #data d INNER JOIN
(SELECT cap.ResId,Sum(ISNULL(Cap.HrsNorm,0)+ISNULL(Cap.HrsHoli,0)) AS HrsNorm FROM cap INNER JOIN #data d ON d.empid=cap.ResId AND CAST(DayDate AS DATE) BETWEEN #startdate AND #enddate
GROUP BY cap.ResId) data ON d.EmpId=data.ResId
UPDATE d SET d.[Used Time]=data.UsedHours FROM #data d INNER JOIN
(SELECT tr.EmpId,SUM(tr.RegHrs) AS UsedHours FROM TimeReg AS tr WHERE CAST(RegDate AS DATE) BETWEEN #startdate AND #enddate
and reghrs IS NOT null
GROUP BY tr.EmpId ) data ON d.EmpId=data.EmpId
UPDATE d SET [Basic Time]=[Used Time],d.[Billable Target %]=100 FROM #data d WHERE EmployeeType=3
UPDATE d SET [Basic Time]=ISNULL([Basic Time],0),[Used Time]=ISNULL([Used Time],0) FROM #data d
UPDATE d
SET d.Holiday = data.UsedHours
FROM #data d
INNER JOIN
(
SELECT tr.EmpId,SUM(tr.RegHrs) AS UsedHours
FROM TimeReg AS tr
INNER JOIN RessFerie AS rf ON rf.RecId=tr.EmpHoliRecId
INNER JOIN AbsenceCode AS ac ON ac.Id=rf.AbsenceID
INNER JOIN job ON Job.JobID = tr.JobId
INNER JOIN RessProjekter AS rp ON rp.ProjektID = Job.ProjektID
INNER JOIN CUST ON cust.CustId=rp.RessID
WHERE CAST(RegDate AS DATE) BETWEEN #startdate AND #enddate AND RegHrs IS NOT NULL AND cust.CustTypeId=5 AND job.JobTypeID<>#PitchJobTypeId AND ac.Descr<>'Recovery Day'
GROUP BY tr.EmpId
) data ON d.EmpId = data.EmpId;
UPDATE d
SET d.Recovery = data.UsedHours
FROM #data d
INNER JOIN
(
SELECT tr.EmpId,SUM(tr.RegHrs) AS UsedHours
FROM TimeReg AS tr
INNER JOIN RessFerie AS rf ON rf.RecId=tr.EmpHoliRecId
INNER JOIN AbsenceCode AS ac ON ac.Id=rf.AbsenceID
INNER JOIN job ON Job.JobID = tr.JobId
INNER JOIN RessProjekter AS rp ON rp.ProjektID = Job.ProjektID
INNER JOIN CUST ON cust.CustId=rp.RessID
WHERE CAST(RegDate AS DATE) BETWEEN #startdate AND #enddate AND RegHrs IS NOT NULL AND cust.CustTypeId=5 AND job.JobTypeID<>#PitchJobTypeId AND ac.Descr='Recovery Day'
GROUP BY tr.EmpId
) data ON d.EmpId = data.EmpId;
UPDATE d
SET d.Illness = data.UsedHours
FROM #data d
INNER JOIN
(
SELECT tr.EmpId,SUM(tr.RegHrs) AS UsedHours
FROM TimeReg AS tr
INNER JOIN job ON Job.JobID = tr.JobId
INNER JOIN RessProjekter AS rp ON rp.ProjektID = Job.ProjektID
INNER JOIN CUST ON cust.CustId=rp.RessID
WHERE CAST(RegDate AS DATE) BETWEEN #startdate AND #enddate AND RegHrs IS NOT NULL AND cust.CustTypeId=6 AND job.JobTypeID<>#PitchJobTypeId
GROUP BY tr.EmpId
) data ON d.EmpId = data.EmpId;
UPDATE d
SET d.[Billable Time] = data.UsedHours
FROM #data d
INNER JOIN
(
SELECT tr.EmpId,SUM(tr.RegHrs) AS UsedHours
FROM TimeReg AS tr
INNER JOIN job ON Job.JobID = tr.JobId
INNER JOIN RessProjekter AS rp ON rp.ProjektID = Job.ProjektID
INNER JOIN CUST ON cust.CustId=rp.RessID
LEFT JOIN #Billablejob AS bj ON job.JobID=bj.Jobid
WHERE CAST(RegDate AS DATE) BETWEEN #startdate AND #enddate AND RegHrs IS NOT NULL AND (job.DebitFlg=1 OR bj.Jobid IS NOT NULL) AND (cust.CustTypeId=1 OR cust.CustTypeId=2) AND job.JobTypeID<>#PitchJobTypeId AND job.JobTypeID<>#ClientInvestmentJobTypeId AND job.JobTypeID<>#AdministrationJobTypeId
GROUP BY tr.EmpId
) data ON d.EmpId = data.EmpId;
UPDATE d
SET d.[Non Billable Time] = data.UsedHours
FROM #data d
INNER JOIN
(
SELECT tr.EmpId,SUM(tr.RegHrs) AS UsedHours
FROM TimeReg AS tr
INNER JOIN job ON Job.JobID = tr.JobId
INNER JOIN RessProjekter AS rp ON rp.ProjektID = Job.ProjektID
INNER JOIN CUST ON cust.CustId=rp.RessID
LEFT JOIN #Billablejob AS bj ON job.JobID=bj.Jobid
WHERE CAST(RegDate AS DATE) BETWEEN #startdate AND #enddate AND RegHrs IS NOT NULL AND ((bj.Jobid IS NULL and job.DebitFlg=0 AND (cust.CustTypeId=1 OR cust.CustTypeId=2) AND job.JobTypeID<>#PitchJobTypeId AND job.JobTypeID<>#AdministrationJobTypeId) OR job.JobTypeID=#ClientInvestmentJobTypeId)
GROUP BY tr.EmpId
) data ON d.EmpId = data.EmpId;
UPDATE d
SET d.[Pitch Time] = data.UsedHours
FROM #data d
INNER JOIN
(
SELECT tr.EmpId,SUM(tr.RegHrs) AS UsedHours
FROM TimeReg AS tr
INNER JOIN job ON Job.JobID = tr.JobId
INNER JOIN RessProjekter AS rp ON rp.ProjektID = Job.ProjektID
INNER JOIN CUST ON cust.CustId=rp.RessID
WHERE CAST(RegDate AS DATE) BETWEEN #startdate AND #enddate AND RegHrs IS NOT NULL AND tr.EmpHoliRecId IS NULL AND job.JobTypeID=#PitchJobTypeId
GROUP BY tr.EmpId
) data ON d.EmpId = data.EmpId;
UPDATE d
SET d.[Internal Time] = data.UsedHours
FROM #data d
INNER JOIN
(
SELECT tr.EmpId,SUM(tr.RegHrs) AS UsedHours
FROM TimeReg AS tr
INNER JOIN job ON Job.JobID = tr.JobId
INNER JOIN RessProjekter AS rp ON rp.ProjektID = Job.ProjektID
INNER JOIN CUST ON cust.CustId=rp.RessID
WHERE CAST(RegDate AS DATE) BETWEEN #startdate AND #enddate AND RegHrs IS NOT NULL AND tr.EmpHoliRecId IS NULL AND (((cust.CustTypeId=3 OR cust.CustTypeId=4) AND job.JobTypeID<>#PitchJobTypeId AND job.JobTypeID<>#ClientInvestmentJobTypeId) OR job.JobTypeID=#AdministrationJobTypeId)
GROUP BY tr.EmpId
) data ON d.EmpId = data.EmpId;
UPDATE d SET d.[Used Time2]=isnull(d.[Used Time],0)-isnull(d.Recovery,0) FROM #data d
UPDATE d SET d.[Max Billable Hours]=ISNULL(d.[Used Time2],0)-ISNULL(d.Holiday,0)-ISNULL(d.Illness,0) FROM #data d
UPDATE d SET d.[Available Hours]=ISNULL(d.[Basic Time],0)-ISNULL(d.Holiday,0)-ISNULL(d.Illness,0) FROM #data d
UPDATE d SET d.[Office Hours %]=CAST(CASE WHEN ISNULL(d.[Available Hours],0)=0 THEN 0 ELSE d.[Max Billable Hours]/d.[Available Hours]*100 END AS INT) FROM #data d
UPDATE d SET d.[Billable %]=CAST(CASE WHEN ISNULL(d.[Available Hours],0)=0 THEN CASE WHEN ISNULL(d.[Billable Time],0)=0 THEN 100 ELSE 0 END ELSE d.[Billable Time]/d.[Available Hours]*100 END AS INT) FROM #data d
UPDATE d SET d.[Non Billable %]=CAST(CASE WHEN ISNULL(d.[Available Hours],0)=0 THEN 0 ELSE d.[Non Billable Time]/d.[Available Hours]*100 END AS INT) FROM #data d
UPDATE d SET d.[Pitch %]=CAST(CASE WHEN ISNULL(d.[Available Hours],0)=0 THEN 0 ELSE d.[Pitch Time]/d.[Available Hours]*100 END AS INT) FROM #data d
UPDATE d SET d.[Internal %]=CAST(CASE WHEN ISNULL(d.[Available Hours],0)=0 THEN 0 ELSE d.[Internal Time]/d.[Available Hours]*100 END AS INT) FROM #data d
UPDATE d SET d.[Variance to Target %]=ISNULL(d.[Billable %],0)-ISNULL(d.[Billable Target %],0) FROM #data d
SELECT d.Name,
d.[Employee Type],
d.[Basic Time],
d.[Used Time] AS [Total Time posted],
isnull(d.Holiday,0)+isnull(d.Illness,0) [Absence],
d.Recovery,
d.[Billable Time],
d.[Non Billable Time],
d.[Pitch Time],
d.[Internal Time],
isnull(d.[Used Time2],0) AS [Used Time],
d.[Max Billable Hours],
d.[Available Hours],
CAST(d.[Office Hours %] AS NVARCHAR(50))+'%' AS [Office Hours %],
CAST(d.[Billable %] AS NVARCHAR(50))+'%' AS [Billable %],
CAST(d.[Non Billable %] AS NVARCHAR(50))+'%' AS [Non Billable %],
CAST(d.[Pitch %] AS NVARCHAR(50))+'%' AS [Pitch %],
CAST(d.[Internal %] AS NVARCHAR(50))+'%' AS [Internal %],
CAST(d.[Billable Target %] AS NVARCHAR(50))+'%' AS [Billable Target %],
CAST(d.[Variance to Target %] AS NVARCHAR(50))+'%' AS [Variance to Target %],
d.Department,
d.[Job Role],
d.Market
FROM #data d
ExitSp:
That produces a large table containing data similar to below:
I would like to include a Pivot sub query to wrap up various elements of the above original query but cannot seem to get this to work.
I have tried including the below at the beginning of my original script::
SELECT [Department], [Employee Type],[Basic Time]
FROM
(
and then:
) As SourceTable
PIVOT
(
SUM ([Basic Time])
FOR [[Basic Time]] IN ([Employee Type])
) AS PivotTable
At the end but with no luck?
Can anyone help out in the best way to do this?

You need to specify each possible value for Employee Type as column names, for example:
SELECT Name, Department, Permanent AS BasicTime_Permanent, Freelance AS BasicTime_Freelance
FROM
(
SELECT Name, Department, [Employee Type], [Basic Time]
FROM (
...
) x
) As SourceTable
PIVOT (
SUM ([Basic Time])
FOR [Employee Type] IN (Permanent, Freelance)
) AS PivotTable
See the example in the docs.
However, it seems you need multiple PIVOT queries (one for [Basic Time], one for [Total time posted], etc) that should be later joined together (with outer joins). It looks to me as too much trouble for a result that would be too wide anyway.

Related

Converting SQL view that uses functions to work in snowflake

I have a view in SQL server that i'm trying to convert to work in snowflake. The view uses two functions within it that are called to join onto another table.
I'm following steps provided by another user, but i'm getting lost somewhere in the middle and feel a little stuck.
Here is the query for the SQL Server view:
ALTER VIEW [proj].[pvw_PowerBI_ScrapList]
AS
SELECT
e.Name AS ProductionUnit,
temp.DateTime AS DateTime,
s.Reference AS Shift,
CONVERT(TIME, temp.DateTime) AS Time,
CONVERT(DATE, temp.DateTime - ISNULL((SELECT CAST(MIN(s_first.FromTimeOfDay) AS DateTime) FROM Shift s_first WHERE s_first.FromDay = s.FromDay AND s_first.ShiftCalendarID = s.ShiftCalendarID), CAST('6:00' AS DateTime))) AS ProductionDate,
temp.ScrapReason AS ScrapReason,
temp.Quantity AS ScrapQuantity,
'Manually Registered' AS RegistrationType
FROM (SELECT
CAST(SUM(sreg.ScrapQuantity) AS int) AS Quantity,
sreas.Name As ScrapReason,
DATEADD(MINUTE, 30 * (DATEPART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, sreg.ScrapTime), 0)) AS DateTime,
srer.EquipmentID AS EquipmentID
FROM qms.ScrapRegistration sreg WITH (NOLOCK)
INNER JOIN qms.ScrapReason sreas WITH (NOLOCK) ON sreas.ID = sreg.ScrapReasonID -- creating CTE of this table
INNER JOIN WorkRequest wr WITH (NOLOCK) ON wr.ID = sreg.WorkRequestID -- CREATE CTE OF THIS TABLE
INNER JOIN SegmentRequirementEquipmentRequirement srer WITH (NOLOCK) ON srer.SegmentRequirementID = wr.SegmentRequirementID -- CREATE CTE OF THIS TABLE
GROUP BY DATEADD(MINUTE, 30 * (DATEPART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, sreg.ScrapTime), 0)), srer.EquipmentID, sreas.Name) temp
INNER JOIN Equipment e WITH (NOLOCK) ON e.ID = temp.EquipmentID -- CREATE CTE OF THIS TABLE
INNER JOIN ShiftCalendar sc WITH (NOLOCK) ON sc.ID = dbo.cfn_GetEquipmentShiftCalendarID(e.ID, temp.DateTime) -- CREATE CTE OF THIS TABLE
INNER JOIN Shift s WITH (NOLOCK) ON s.ID = dbo.cfn_GetShiftIDFromDateTime(temp.DateTime, sc.ID) -- CREATE CTE OF THIS TABLE
UNION
SELECT
e.Name AS ProductionUnit,
temp.DateTime AS DateTime,
s.Reference AS Shift,
CONVERT(TIME, temp.DateTime) AS Time,
CONVERT(DATE, temp.DateTime - ISNULL((SELECT CAST(MIN(s_first.FromTimeOfDay) AS DateTime) FROM Shift s_first WHERE s_first.FromDay = s.FromDay AND s_first.ShiftCalendarID = s.ShiftCalendarID), CAST('6:00' AS DateTime))) AS ProductionDate,
temp.ScrapReason AS ScrapReason,
temp.Quantity AS ScrapQuantity,
'Auto Registered' AS RegistrationType
FROM (SELECT
SUM(ISNULL(asr.ScrapQuantity, 0)) AS Quantity,
sreas.Name As ScrapReason,
DATEADD(MINUTE, 30 * (DATEPART(MINUTE, asr.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, asr.ScrapTime), 0)) AS DateTime,
srer.EquipmentID AS EquipmentID
FROM proj.AutoScrapRegistration asr WITH (NOLOCK)
INNER JOIN qms.ScrapReason sreas WITH (NOLOCK) ON sreas.ID = asr.ScrapReasonID
INNER JOIN WorkRequest wr WITH (NOLOCK) ON wr.ID = asr.WorkRequestID
INNER JOIN SegmentRequirementEquipmentRequirement srer WITH (NOLOCK) ON srer.SegmentRequirementID = wr.SegmentRequirementID
GROUP BY DATEADD(MINUTE, 30 * (DATEPART(MINUTE, asr.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, asr.ScrapTime), 0)), srer.EquipmentID, sreas.Name) temp
INNER JOIN Equipment e WITH (NOLOCK) ON e.ID = temp.EquipmentID
INNER JOIN ShiftCalendar sc WITH (NOLOCK) ON sc.ID = dbo.cfn_GetEquipmentShiftCalendarID(temp.EquipmentID, temp.DateTime) -- the function is called here
INNER JOIN Shift s WITH (NOLOCK) ON s.ID = dbo.cfn_GetShiftIDFromDateTime(temp.DateTime, sc.ID) -- the function is called here
i'm ignoring the union for now to try and get something simply working.
The functions are highlighted in this post How to conver this SQL server Function into a CTE in snowflake
Here is what i have so far:
WITH table_ScrapRegistration (
Quantity
,ScrapReason
,DATETIME
,EquipmentID
,ScrapReasonID
,WorkRequestID
,SegmentRequirementID
)
AS (
SELECT CAST(SUM(sreg.ScrapQuantity) AS INT) AS Quantity
,sreas.Name AS ScrapReason
,DATEADD(MIN, 30 * (DATE_PART(MINUTE, sreg.ScrapTime) / 30)::INT, date_trunc('HOUR', sreg.ScrapTime)) AS DATETIME
,srer.EquipmentID AS EquipmentID
,sreas.ID AS ScrapReasonID
,wr.ID AS WorkRequestID
,srer.SegmentRequirementID AS SegmentRequirementID
FROM DB_BI_DEV.RAW_CPMS_LAG.ScrapRegistration sreg
INNER JOIN DB_BI_DEV.RAW_CPMS_LAG.ScrapReason sreas ON sreas.ID = sreg.ScrapReasonID -- CREATE CTE OF THIS TABLE
INNER JOIN DB_BI_DEV.RAW_CPMS_LAG.WorkRequest wr ON wr.ID = sreg.WorkRequestID -- CREATE CTE OF THIS TABLE
INNER JOIN DB_BI_DEV.RAW_CPMS_LAG.SegmentRequirementEquipmentRequirement srer ON srer.SegmentRequirementID = wr.SegmentRequirementID -- CREATE CTE OF THIS TABLE
GROUP BY DATEADD(MIN, 30 * (DATE_PART(MINUTE, sreg.ScrapTime) / 30)::INT, date_trunc('HOUR', sreg.ScrapTime))
,srer.EquipmentID
,sreas.Name
,sreas.ID
,wr.ID
,srer.SegmentRequirementID
)
,table_scrapreason (
name
,ID
)
AS (
SELECT name
,ID
FROM DB_BI_DEV.RAW_CPMS_LAG.ScrapReason
)
,table_workrequest (
ID
,SegmentRequirementID
) -- this is from a join)
AS (
SELECT id
,SegmentRequirementID
FROM DB_BI_DEV.RAW_CPMS_LAG.WorkRequest
)
,table_SegmentRequirementEquipmentRequirement (
EquipmentID
,SegmentRequirementID
)
AS (
SELECT EquipmentID
,SegmentRequirementID
FROM DB_BI_DEV.RAW_CPMS_LAG.SegmentRequirementEquipmentRequirement
)
,table_equipment (
id
,name
,ParentEquipmentID
,ShiftCalendarEntityNumber
)
AS (
SELECT id
,name
,ParentEquipmentID
,ShiftCalendarEntityNumber
FROM DB_BI_DEV.RAW_CPMS_LAG.Equipment
)
,table_ShiftCalendar (
id,
entitynumber,
begindate,
enddate,
name,
PeriodInDays
)
AS (
SELECT id,
entitynumber,
begindate,
enddate,
name,
PeriodInDays
FROM DB_BI_DEV.RAW_CPMS_LAG.ShiftCalendar)
,table_shift (
ID
,Reference
,FromDay
)
AS -- this is from the temp table
(
SELECT ID
,Reference
,FromDay
FROM DB_BI_DEV.RAW_CPMS_LAG.shift
)
,temp_sub_select
AS (
SELECT sreg.Quantity AS Quantity
,sreas.name AS ScrapReason
,timeadd('minute', TRUNCATE (minute(sreg.DATETIME) / 30) * 30, date_trunc('hour', sreg.DATETIME)) AS DATETIME
,srer.EquipmentID AS EquipmentID
FROM table_ScrapRegistration sreg
INNER JOIN table_scrapreason sreas ON sreas.ID = sreg.ScrapReasonID -- CREATE CTE OF THIS TABLE
INNER JOIN table_workrequest wr ON wr.ID = sreg.WorkRequestID -- CREATE CTE OF THIS TABLE
INNER JOIN table_SegmentRequirementEquipmentRequirement srer ON srer.SegmentRequirementID = wr.SegmentRequirementID -- CREATE CTE OF THIS TABLE
GROUP BY sreg.Quantity
,sreas.name
,timeadd('minute', TRUNCATE (minute(sreg.DATETIME) / 30) * 30, date_trunc('hour', sreg.DATETIME))
,srer.EquipmentID
)
--select * from cte_GetEquipmentShiftCalendarID_part_a
--when i run this i get results
, cte_GetEquipmentShiftCalendarID_part_a
as (
WITH recursive rec_cte(id, parentequipmentid, shiftcalendarentitynumber) AS (
SELECT ID,
ParentEquipmentID,
ShiftCalendarEntityNumber
FROM table_equipment
UNION ALL
SELECT r.ID,
p.ParentEquipmentID,
p.ShiftCalendarEntityNumber
FROM rec_cte AS r
INNER JOIN table_equipment p ON p.ID = r.ParentEquipmentID
AND r.ShiftCalendarEntityNumber IS NULL
)
SELECT c.id,
sc.id AS shiftCalendarID,
sc.begindate,
sc.enddate
FROM rec_cte AS c
LEFT JOIN table_shiftcalendar AS sc ON sc.entitynumber = c.ShiftCalendarEntityNumber
WHERE shiftcalendarentitynumber IS NOT NULL
)
select * from cte_GetEquipmentShiftCalendarID_part_a
-- when i run this, i dont get any results.

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

How to merge null column in sql table

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

Resources