I have this dataset where I have a time-series with in the YYYYMM format. I have two columns which basically as true/false flags. I would like to add two extra columns based on these true/false flags that retrieves the current range:
Default Cure
201301 0 NULL
201302 0 NULL
201303 0 NULL
201304 1 NULL
201305 1 NULL
201306 1 NULL
201307 1 NULL
201308 NULL 0
201309 NULL 0
201310 NULL 1
201311 0 NULL
201312 0 NULL
201401 0 NULL
201402 0 NULL
201403 1 NULL
201404 1 NULL
201405 0 NULL
201406 0 NULL
201407 NULL 1
201408 NULL 0
201409 NULL 0
201410 NULL 0
201411 NULL 0
201412 NULL 0
I this dataset you can see the Default column being set to 1 for the periods 201304, 05, 06, 07 and the Cure column is set to 1 in the period 201310.
This basically means the Default timeseries is valid from period 201304 until period 201310. Ultimately I would like to generate the following set:
Default Cure DefaultPeriod CurePeriod
201301 0 NULL NULL NULL
201302 0 NULL NULL NULL
201303 0 NULL NULL NULL
201304 1 NULL 201304 201310
201305 1 NULL 201304 201310
201306 1 NULL 201304 201310
201307 1 NULL 201304 201310
201308 NULL 0 201304 201310
201309 NULL 0 201304 201310
201310 NULL 1 201304 201310
201311 0 NULL NULL NULL
201312 0 NULL NULL NULL
201401 0 NULL NULL NULL
201402 0 NULL NULL NULL
201403 1 NULL 201403 201407
201404 1 NULL 201403 201407
201405 0 NULL 201403 201407
201406 0 NULL 201403 201407
201407 NULL 1 201403 201407
201408 NULL 0 NULL NULL
201409 NULL 0 NULL NULL
201410 NULL 0 NULL NULL
201411 NULL 0 NULL NULL
201412 NULL 0 NULL NULL
Multiple ranges can occur but they cannot overlap. How would I go about achieving this. I have tried to do all sorts of min/max period join on the same table, but I can't seem to find a working solution.
This was a real thinker :)
Basically I am dividing up the data on the "Cure" dates (c1), numbering each group(c2), then looking for mins and maxes within each group (c3 C4), then applying some logic to filter out the rows that come before the min.
declare #t table
(
[Month] varchar(6),
[Default] bit,
[Cure] bit
);
insert into #t values('201301', 0, NULL);
insert into #t values('201302', 0, NULL);
insert into #t values('201303', 0, NULL);
insert into #t values('201304', 1, NULL);
insert into #t values('201305', 1, NULL);
insert into #t values('201306', 1, NULL);
insert into #t values('201307', 1, NULL);
insert into #t values('201308', NULL, 0);
insert into #t values('201309', NULL, 0);
insert into #t values('201310', NULL, 1);
insert into #t values('201311', 0, NULL);
insert into #t values('201312', 0, NULL);
insert into #t values('201401', 0, NULL);
insert into #t values('201402', 0, NULL);
insert into #t values('201403', 1, NULL);
insert into #t values('201404', 1, NULL);
insert into #t values('201405', 0, NULL);
insert into #t values('201406', 0, NULL);
insert into #t values('201407', NULL, 1);
insert into #t values('201408', NULL, 0);
insert into #t values('201409', NULL, 0);
insert into #t values('201410', NULL, 0);
insert into #t values('201411', NULL, 0);
insert into #t values('201412', NULL, 0);
with c1 as
(
select min([Month]) [Month], 1 x from #t
union all
select [Month],1 from #t
where Cure = 1
),
c2 as
(
select t.[Month],[Default],[Cure],
sum(x) over (order by t.[Month] rows between unbounded preceding and 1 preceding) grp
from #t t
left outer join c1 on c1.[Month] = t.[Month]
),
c3 as
(
select grp, min([Month]) [Month]
from c2
where [Default] = 1
group by grp
),
c4 as
(
select grp, max([Month]) [Month]
from c2
where [Cure] = 1
group by grp
)
select c2.[Month], c2.[Default], c2.[Cure],
case when c2.[Month] >= c3.[Month] then c3.[Month] else null end as DefaultPeriod,
case when c2.[Month] >= c3.[Month] then c4.[Month] else null end as CurePeriod
from c2
left outer join c3 on c2.grp = c3.grp
left outer join c4 on c2.grp = c4.grp
Related
I have a table (showing temp table)
CREATE TABLE #TempTable
(
TempID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
CustID INT NOT NULL,
RODate DATE NULL,
Operation INT NULL
);
This table has this sample data:
INSERT INTO #TempTable (CustID, RODate, Operation)
VALUES (10, DATEADD(MONT, -2, GETDATE()), 2),
(10, DATEADD(MONT, -1, GETDATE()), 3),
(10, GETDATE(), 5)
So table have below data
TempID CustID RODate Operation
-----------------------------------------------------------
1 10 2019-03-17 2
2 10 2019-04-17 3
3 10 2019-05-17 5
Requirement is I will get one integer variable in parameter which is #noOfOperation, let's say its value is 10
I will also get no of months in parameter, let's say it's 3
I have to query the table to return data for last 3 months only (excluding current month (date asc)
Then I have to deduct #noOfOperation from the table and update.
Deduction will be based on availability in operation column.
For example: in this case first we will deduct from 2019-03-17
10 - 2 = 8 (operation column for this row becomes 0)
Next we will deduct from 2019-04-17
8 - 3 = 5 (operation column for this row becomes 0)
Similarly for 2019-05-17
5-5 = 0 (operation column for this row becomes 0)
I have to check if #noOfOperation is less than or more than the number of operation of individual months then do the above accordingly
Check this out, The idea is to use the accumulated operation and then subtracted the needed value as below:
declare #TempTable TABLE
(
TempID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
CustID INT NOT NULL,
RODate DATE NULL,
Operation INT NULL
);
INSERT INTO #TempTable (CustID, RODate, Operation)
VALUES (10, DATEADD(MONTH, -2, GETDATE()), 5),
(10, DATEADD(MONTH, -1, GETDATE()), 6),
(10, GETDATE(), 7)
select * from #TempTable
Declare #noOfOperation int =8
Declare #noOfMonths int =3
Declare #StartDate date,#DateEnd date,#avNoOfOperation int
--get the range you are working for
select
#StartDate=cast(cast(year(dateadd(Month,-#noOfMonths+1,getdate())) as varchar(4))+'-'+cast(Month(dateadd(Month,-#noOfMonths+1,getdate())) as varchar(2))+'-01' as date)
,#DateEnd=dateadd(day,-1,cast(cast(year(getdate()) as varchar(4))+'-'+cast(Month(getdate()) as varchar(2))+'-01' as date)) ;
--get the total of avaliable operation, for validating before subtracting
select #avNoOfOperation=sum(t.Operation) from #TempTable t where cast(t.RODate as date) between #StartDate and #DateEnd
--review the variables if needed
--select #StartDate [#StartDate],#DateEnd [#DateEnd],#avNoOfOperation [#avNoOfOperation]
if(#avNoOfOperation>=#noOfOperation and #noOfOperation>0)
begin
--only here we can start subtracting
;with DataIncluded as (
select *,#noOfOperation [noOfOperation],sum(Operation) over (order by RODate) [AcOp] from #TempTable t where cast(t.RODate as date) between #StartDate and #DateEnd
),SubtractDataSet as (
select *,AcOp-#noOfOperation [leftOp],
case when (AcOp-#noOfOperation)<=0 then 0 else
case when (AcOp-#noOfOperation)<Operation then AcOp-#noOfOperation else Operation end end [UpOp]
from DataIncluded
)
Update #TempTable
set A.Operation=B.[UpOp]
From #TempTable A
inner join SubtractDataSet B on A.TempID=B.TempID
end
select * from #TempTable
Note: Im not using the current month so my output is different then the one you suggested. if the inputs was as follow:
TempID CustID RODate Operation
1 10 2019-03-17 5
2 10 2019-04-17 6
3 10 2019-05-17 7
The output would be :-
TempID CustID RODate Operation
1 10 2019-03-17 0
2 10 2019-04-17 3
3 10 2019-05-17 7
--Change the value of #OperationsToBeDeducted, to see different results
declare #OperationsToBeDeducted int
declare #OperationsRemaining int
declare #RODate date
set #OperationsToBeDeducted = 4
declare #TempID int
set #TempID = 1
DROP TABLE IF EXISTS #TempOperation
create table #TempOperation
(
TempID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
CustID INT NOT NULL,
RODate DATE NULL,
Operation INT NULL
);
insert into #TempOperation (CustID,RODate,Operation)
values
(10,DATEADD(month, -3, getdate()),2),
(10,DATEADD(month, -2, getdate()), 2),
(10,DATEADD(month, -1, getdate()),3)
DROP TABLE IF EXISTS #TempOperation2
create table #TempOperation2
(
TempID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
CustID INT NOT NULL,
RODate DATE NULL,
Operation INT NULL
);
insert into #TempOperation2 select CustID,RODate, Operation from #TempOperation
select * from #TempOperation2 order by RODate asc
declare #maxID int;
select #maxID = max(TempID) from #TempOperation2
while (#TempID <= #maxID)
begin
set #OperationsRemaining = 0
select #OperationsRemaining = Operation, #RODate = RODate from #TempOperation2 where TempID = #TempID
if(#OperationsToBeDeducted is not null and #OperationsRemaining is not null and
#OperationsRemaining > 0 and #OperationsRemaining > #OperationsToBeDeducted)
begin
update #TempOperation set Operation = #OperationsRemaining - #OperationsToBeDeducted where TempID = #TempID
set #OperationsToBeDeducted = 0
end
else if(#OperationsToBeDeducted is not null and #OperationsRemaining is not null and
#OperationsRemaining > 0 and #OperationsRemaining <= #OperationsToBeDeducted)
begin
set #OperationsToBeDeducted = #OperationsToBeDeducted - #OperationsRemaining
update #TempOperation set Operation = #OperationsRemaining - #OperationsRemaining where TempID = #TempID
end
SET #TempID = #TempID + 1
end
select * from #TempOperation order by RODate asc
DROP TABLE #TempOperation
DROP TABLE #TempOperation2
I am trying to pivot rows into columns with Tsql and also eliminate Nulls. How do I do this? My current query:
IF OBJECT_ID(N'tempdb..#test_data') IS NOT NULL drop table #test_data
create table #test_data (
question_caption varchar(max),
[0] varchar(max),
[1] varchar(max),
[2] varchar(max),
[3] varchar(max))
insert #test_data values('q1','abc',Null,Null,Null)
insert #test_data values('q2',Null,'def',Null,Null)
insert #test_data values('q3',Null,Null,'ghi',Null)
insert #test_data values('q4',Null,Null,Null,'jkl')
select * from #test_data
pivot (
Max([0])
For question_caption in ([0],[1],[2],[3])
) as PivotTable
Output:
question_caption 0 1 2 3
q1 abc NULL NULL NULL
q2 NULL def NULL NULL
q3 NULL NULL ghi NULL
q4 NULL NULL NULL jkl
What I want:
q1 q2 q3 q4
abc def ghi jkl
How can I achieve this? The above query has the error:
Msg 265, Level 16, State 1, Line 4
The column name "0" specified in the PIVOT operator conflicts with the existing column name in the PIVOT argument.
I have tried multiple Pivot examples, but all of them have resulted in one error or another.
You can do with a simple max case:
select [q1]=max(case when question_caption = 'q1' then [0] else null end),
[q2]=max(case when question_caption = 'q2' then [1] else null end),
[q3]=max(case when question_caption = 'q3' then [2] else null end),
[q4]=max(case when question_caption = 'q4' then [3] else null end)
from #test_data
or the pivot:
select [q1], [q2], [q3], [q4]
from ( select question_caption,
coalesce([0],[1],[2],[3])
from #test_data
) s (c, v)
pivot (max(v) for c in ([q1], [q2], [q3], [q4])) p
I have the following table structure.
I just want to update SubId to all the rows where it is null and where the RawLineNumber is ascending by 1 and also the SeqNumber ascending by 1.
RawlineNumber Claimid SubId SeqNumber
1 6000 A100 1
2 6000 NULL 2
3 6000 NULL 3
10 6000 A200 1
11 6000 NULL 2
25 6000 A300 1
26 6000 NULL 2
27 6000 NULL 3
I want to update
SubId of RawLineNumber 2 and 3 with A100,
SubId of RawLineNumber 11 with A200,
SubId of RawLineNumber 26 and 27 with A300.
I have a cursor which does the job but can I have a CTE to take care of it ?
UPDATE m
SET subid = q.subid
FROM mytable m
CROSS APPLY
(
SELECT TOP 1 subid
FROM mytable mi
WHERE mi.rawLineNumber < m.rawLineNumber
AND mi.subid IS NOT NULL
ORDER BY
rawLineNumber DESC
) q
WHERE m.subid IS NULL
Since a recusive solution was requested, I decided to write one. Also it works for gaps in Seqnumbers and RawlineNumber
declare #t table (RawlineNumber int, Claimid int, SubId varchar(5), SeqNumber int)
insert #t values(1, 6000, 'A100', 1)
insert #t values(2, 6000, NULL, 2)
insert #t values(3, 6000, NULL, 3)
insert #t values(10, 6000, 'A200', 1)
insert #t values(11, 6000, NULL, 2)
insert #t values(25, 6000, 'A300', 1)
insert #t values(26, 6000, NULL, 2)
insert #t values(27, 6000, NULL, 3)
;with cte as
(
select Rawlinenumber, SeqNumber, SubId
from #t where SubId is not null and SeqNumber = 1
union all
select t.Rawlinenumber, t.SeqNumber, c.SubId
from cte c
join
#t t
on c.Rawlinenumber + 1 = t.Rawlinenumber
and c.SeqNumber + 1 = t.SeqNumber
where t.SubId is null and t.SeqNumber > 1
)
update t
set SubId = c.SubId
from #t t join cte c
on c.Rawlinenumber = t.Rawlinenumber
where t.SeqNumber > 1
select * from #t
A not-so simple SQL script should achieve what you want:
update my_table t1 set t1.subid =
(select t2.subid from my_table t2
where t2.rawlinenumber < t1.rawlinenumber
and t2.seqnumber = 1
and t2.rawlinenumber = (
select max(t3.rawlinenumber)
from my_table t3
where t3.seq_number = 1
and t3.rawlinenumber <= t2.rawlinenumber)
where t1.subid is null;
The inner subselect (T3) gives us the last row having seqnumber = 1 before the current line,
the outer subselect gives us the SubID for this row (using windowing functions would be more efficient, but since you didn't mention a specific RDBMS, I stick with this :-) )
I've a product table with product_id and 100+ attributes. The product_id is text whereas the attribute columns are integer, i.e. 1 if the attribute exists. When the Postgresql crosstab is run, non-matching atrributes return null values. How do I replace nulls with zeros instead.
SELECT ct.*
INTO ct3
FROM crosstab(
'SELECT account_number, attr_name, sub FROM products ORDER BY 1,2',
'SELECT DISTINCT attr_name FROM attr_names ORDER BY 1')
AS ct(
account_number text,
Attr1 integer,
Attr2 integer,
Attr3 integer,
Attr4 integer,
...
)
Replace this result:
account_number Attr1 Attr2 Attr3 Attr4
1.00000001 1 null null null
1.00000002 null null 1 null
1.00000003 null null 1 null
1.00000004 1 null null null
1.00000005 1 null null null
1.00000006 null null null 1
1.00000007 1 null null null
with this below:
account_number Attr1 Attr2 Attr3 Attr4
1.00000001 1 0 0 0
1.00000002 0 0 1 0
1.00000003 0 0 1 0
1.00000004 1 0 0 0
1.00000005 1 0 0 0
1.00000006 0 0 0 1
1.00000007 1 0 0 0
A workaround would be to do a select account_number, coalesce(Attr1,0)... on the result. But typing out coalesce for each of the 100+ columns is rather unyieldly. Is there a way to handle this using crosstab? Thanks
You can use coalesce:
select account_number,
coalesce(Attr1, 0) as Attr1,
coalesce(Attr2, 0) as Attr2,
etc
if you can put those Attrs into a table like
attr
-----
Attr1
Attr2
Attr3
...
then you could automatically generate the repeating coalesce statement like
SELECT 'coalesce("' || attr || '", 0) "'|| attr ||'",' from table;
to save some typing.
I am trying to develop a T-SQL query which will do the following:
ROUND(100 * A / B, 1)
Simple in concept, but it's tricky because of possible B=0 denominator and also because of A and B variables. What I expect is a percent value like 93.2 (given in this format without %). Or even 932 would be acceptable since I could convert it later.
But instead, I'm currently getting 151, which is the number of records.
A = CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1 ELSE 0 END
B = CASE WHEN [Date_Completed] IS NOT NULL THEN 1 ELSE 0 END
My current logic only divides A/B if B is not equal to zero. Can you please help me fix this? p.s. all fields above are from the same table A.
I tried:
SELECT CASE WHEN t.VarB<>0 THEN ROUND(100 * t.VarA / t.VarB, 1)
ELSE 0 /* or whatever you'd want to return in this case */
END
FROM (SELECT CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1
ELSE 0
END AS VarA,
CASE WHEN [Date_Completed] IS NOT NULL THEN 1
ELSE 0
END AS VarB
FROM EXCEL.Batch_Records A) t
But I got 33000 rows returned instead of just one, where each row = 100 or 0.
Good idea, Conrad! I tested your solution and it works if I just want that one value. But what I didn't tell you was that there are additional values I need returned from same query. When I tried adding in the other value calculations, I got syntax errors. So here is my current query. How should htis be rewritten please?
select
SUM(CASE WHEN A.DATE_RECEIVED IS NOT NULL THEN 1 ELSE 0 END) AS NUM_RECEIVED,
SUM(CASE WHEN [Date_Completed] IS NOT NULL THEN 1 ELSE 0 END) AS NUM_COMPLETE_OF_OPENED,
SUM(CASE WHEN A.DATE_COMPLETED IS NOT NULL THEN 1 ELSE 0 END) AS NUM_COMPLETED_IN_MONTH,
SUM(CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1 ELSE 0 END) AS NUM_WITHOUT_ERROR,
round(100 * a/b , 1)
from
(select
sum(CASE
WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN
1.0
ELSE 0.0 END) A,
sum(CASE WHEN [Date_Completed] IS NOT NULL THEN
1.0 ELSE 0.0 END) B
FROM EXCEL.Batch_Records a
LEFT JOIN EXCEL.QC_CODES d ON a.Part_Number = d.CODE_ID
WHERE (a.[Group] = #GROUP or #GROUP = '' OR #GROUP IS NULL) AND A.Date_Received >= #STARTDATE AND A.Date_Received <= #ENDDATE
Conrad correctly advised me that #TEMP1 was an empty table. But now I populated it and successfully designed this query with his help:
SET #STARTDATE = '1/1/11'
SET #ENDDATE = '1/31/11'
SET #GROUP = 'INTERMEDIATES_FISH'
--SET #TABLE_TITLE = 'BATCH RECORD SUCCESS RATE'
--SET #DEPT = 'QC'
IF EXISTS(SELECT * FROM TEMPDB.INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '#TEMP1%')
DROP TABLE #TEMP1
--CREATE TABLE #TEMP1 ( MFG int , MFG2 int , QC int, QC2 INT , [Group] NVARCHAR(MAX), [Date_Completed] datetime, Date_Received datetime)
SELECT
MFG, MFG2, QC, QC2, [GROUP], [DATE_COMPLETED], [DATE_RECEIVED]
INTO #TEMP1
FROM EXCEL.Batch_Records a
WHERE (a.[Group] = #GROUP or #GROUP = '' OR #GROUP IS NULL) AND A.Date_Received >= #STARTDATE AND A.Date_Received <= #ENDDATE
------------------------------------------
;WITH CTE AS
(
SELECT
CASE
WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN
1.0
ELSE 0.0 END A,
CASE WHEN [Date_Completed] IS NOT NULL THEN 1.0 ELSE 0.0 END B,
CASE WHEN A.Date_Received IS NOT NULL THEN 1 ELSE 0 END NUM_RECEIVED,
CASE WHEN [Date_Completed] IS NOT NULL THEN 1 ELSE 0 END NUM_COMPLETE_OF_OPENED,
CASE WHEN A.DATE_COMPLETED IS NOT NULL THEN 1 ELSE 0 END NUM_COMPLETED_IN_MONTH,
CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1 ELSE 0 END AS NUM_WITHOUT_ERROR
FROM
#TEMP1 a
--WHERE (a.[Group] = #GROUP or #GROUP = '' OR #GROUP IS NULL) AND A.Date_Received >= #STARTDATE AND A.Date_Received <= #ENDDATE
)
select
round(100 * SUM(A)/SUM(b) , 1) ,
SUM(NUM_RECEIVED) NUM_RECEIVED,
SUM(NUM_COMPLETE_OF_OPENED) NUM_COMPLETE_OF_OPENED,
SUM(NUM_COMPLETED_IN_MONTH) NUM_COMPLETED_IN_MONTH,
SUM(NUM_WITHOUT_ERROR) NUM_WITHOUT_ERROR
FROM CTE
Basically you need to use SUM() to get the sum. You should also use 1.0 and 0.0 so you get decimal values.
You should also do the SUM before the Division
UPDATE
Since you're adding in a number of SUM(CASE statements its probably more readable to move the CASE statments out to a CTE.
CREATE TABLE #Batch_Records (
MFG int ,
MFG2 int ,
QC int,
QC2 INT ,
[Group] int,
[Date_Completed] datetime,
Date_Received datetime)
INSERT INTO #Batch_Records (MFG , MFG2 , QC , QC2 , [Group] , [Date_Completed] , Date_Received )
VALUES (1,null,null,null,1,'1/4/2011','2/4/2011'),
(null,null,null,null,1,'2/2/2011','3/4/2011'),
(1,null,null,null,1,'3/6/2011','4/3/2011'),
(null,null,null,null,1,NULL,'5/4/2011'),
(1,null,null,null,1,'5/4/2011','6/6/2011'),
(1,null,null,null,1,NULL,'7/4/2011')
DECLARE #GROUP int
DECLARE #STARTDATE DateTime
DECLARE #ENDDATE DateTime
SET #GROUP = 1
SET #STARTDATE = '1/1/2001'
SET #ENDDATE = '1/1/2012'
;WITH CTE AS
(
SELECT
CASE
WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN
1.0
ELSE 0.0 END A,
CASE WHEN [Date_Completed] IS NOT NULL THEN
1.0 ELSE 0.0 END B,
CASE WHEN A.Date_Received IS NOT NULL THEN 1 ELSE 0 END NUM_RECEIVED,
CASE WHEN [Date_Completed] IS NOT NULL THEN 1 ELSE 0 END NUM_COMPLETE_OF_OPENED,
CASE WHEN A.DATE_COMPLETED IS NOT NULL THEN 1 ELSE 0 END NUM_COMPLETED_IN_MONTH,
CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1 ELSE 0 END AS NUM_WITHOUT_ERROR
FROM
#Batch_Records a
WHERE
(a.[Group] = #GROUP or #GROUP = '' OR #GROUP IS NULL)
AND A.Date_Received >= #STARTDATE AND A.Date_Received <= #ENDDATE
)
select
round(100 * SUM(A)/SUM(b) , 1) ,
SUM(NUM_RECEIVED) NUM_RECEIVED,
SUM(NUM_COMPLETE_OF_OPENED) NUM_COMPLETE_OF_OPENED,
SUM(NUM_COMPLETED_IN_MONTH) NUM_COMPLETED_IN_MONTH,
SUM(NUM_WITHOUT_ERROR) NUM_WITHOUT_ERROR
FROM CTE
DROP TABLE #Batch_Records