SQL SUM and nested where clause - sql

I have an SQL that takes an id, a start date and an end date as parameters. I then sum certain that are restricted by the where clause. However I need to also sum the same column that doesnt take into account the data params and calculates the total for a particular driver. For example:
SELECT DISTINCT
PMTS.VolunteerId,
PMTS.ChargeRate,
SUM(
CASE [Type]
WHEN 418 THEN Amount
ELSE 0
END
) AS DriverMileage,
SUM(
CASE [Type]
WHEN 1000 THEN Amount
ELSE 0
END
) AS GPMileage,
SUM(
CASE [Type]
WHEN 1001 THEN Amount
ELSE 0
END
) AS Reimbursements,
SUM(
CASE [Type]
WHEN 1002 THEN Amount
ELSE 0
END
) AS MobilePhoneCharges,
SUM(Mileage) AS TotalMileageWeek,
B.TotalMileage,
VOLS.Address1,
VOLS.Address2,
VOLS.Town,
ISNULL(VOLS.Surname, '') + ', ' + ISNULL(VOLS.Forename, '') AS SurnameForename ,
ISNULL(VOLS.County, '') + ' ' + ISNULL(VOLS.PostCode, '') AS CountyPostcode
FROM dbo.vVolunteerPayments PMTS
INNER JOIN dbo.vVolunteers VOLS ON PMTS.VolunteerId = VOLS.VolunteerID
--total mileage
INNER JOIN (select VolunteerId, sum(Mileage) as TotalMileage
FROM dbo.vVolunteerPayments GROUP BY VolunteerId) b ON
b.VolunteerID=PMTS.VolunteerId
WHERE
PMTS.VolunteerId = #volunteerid
AND
PMTS.PaymentEventID = 0
AND
PMTS.DateCreated BETWEEN #sd AND #ed
GROUP BY
PMTS.VolunteerId
,Address1
,Address2
,Town
,County
,PostCode
,Surname
,Forename
,B.TotalMileage
,PMTS.ChargeRate
So the SUM(Mileage) As MileageTotal ignores the where clause

Try this:
Select
a.Name,
SUM(Mileage) As MileageWeek,
SUM(Mileage) As MileageTotal,
b.TotMiles
FROM <table> a
JOIN (select name,sum(Mileage) as TotMiles
FROM <table> GROUP By name) b ON b.name=a.name
WHERE
Journey.DateCreated BETWEEN #startdate AND #enddate
Replace < table > with your actual table name (Journey???)

Eliminate the where clause and do conditional summation:
Select Name,
SUM(case when Journey.DateCreated BETWEEN #startdate AND #enddate then Mileage
else 0
end) As MileageWeek,
SUM(Mileage) As MileageTotal
from Journey
I also added back in the from clause (presumably you left it out accidentally).
SUM(
CASE [Type]
WHEN 418 THEN Amount
ELSE 0
END
) AS DriverMileage,
to
sum(case when [type] = 418 and PMTS.DateCreated BETWEEN #sd AND #ed then amount
else 0
end) as DriverMileage
You may need to include more conditionals from the where clause -- I'm not sure which total you want.

Related

Improve INSERT INTO SELECT Query performance?

I am trying to improve old while loop query. So far tried this but it is still slow. Not sure may be SUM perform slow.
Old query (10 mins+)
ALTER PROCEDURE [dbo].[process_tax]
#userid VARCHAR(10),
#remark NVARCHAR(500),
#tdate DATE,
#roadno NVARCHAR(10),
#inst INT
AS
BEGIN
IF OBJECT_ID('tempdb..#tempProcess_tax_1') IS NOT NULL
DROP TABLE #tempProcess_tax_1
CREATE TABLE #tempProcess_tax_1
(
RowID INT IDENTITY(1, 1),
clid_ INT,
hlid_ INT,
holdinNo_ NVARCHAR(500),
holding_ NVARCHAR(50),
clientid_ NVARCHAR(500),
clientName_ NVARCHAR(500)
)
INSERT INTO #tempProcess_tax_1 (clid_, hlid_, holdinNo_, holding_, clientid_, clientName_)
SELECT
cl.clid AS clid_, cl.id AS hlid_, holdinNo, holding,
ClientID AS clientid_, ClientName AS clientName_
FROM
tx_holding AS cl
WHERE
cl.status = 1 AND cl.roadno = #roadno
AND cl.id IN (SELECT hlid FROM tx_asset WHERE asset IS NOT NULL)
AND cl.clid IN (SELECT id FROM tbl_client WHERE client_type = 'Non-Govt.')
AND cl.id NOT IN (SELECT hlid FROM tx_bill_pay
WHERE YEAR(date_month) = YEAR(#tdate)
AND hlid IS NOT NULL
GROUP BY hlid)
DECLARE #NumberRecords_1 INT, #RowCounter_1 INT
SET #NumberRecords_1 = (SELECT COUNT(*) FROM #tempProcess_tax_1)
SET #RowCounter_1 = 1
WHILE #RowCounter_1 <= #NumberRecords_1
BEGIN
DECLARE #clid_ INT
DECLARE #hlid_ INT
DECLARE #holdinNo_ NVARCHAR(50)
DECLARE #holding_ NVARCHAR(50)
DECLARE #clientid_ NVARCHAR(100)
DECLARE #clientName_ NVARCHAR(250)
DECLARE #bill AS MONEY
DECLARE #sr AS MONEY;
SELECT
#clid_ = clid_,
#hlid_ = hlid_,
#holdinNo_ = holdinNo_, #holding_ = holding_,
#clientid_ = clientid_, #clientName_ = clientName_
FROM
#tempProcess_tax_1
WHERE
RowID = #RowCounter_1
SET #bill = (SELECT
CASE WHEN SUM(netvalue) IS NULL
THEN 0
ELSE SUM(netvalue)
END
FROM
tx_bill
WHERE
hlid = #hlid_
AND itemID NOT IN (8, 6)
AND YEAR(date_month) = YEAR(#tdate))
SET #sr = (SELECT
CASE WHEN SUM(asset * rate / 100) IS NULL
THEN 0
ELSE SUM(asset * rate / 100)
END
FROM
tx_bill
WHERE
hlid = #hlid_
AND itemID = 6
AND YEAR(date_month) = YEAR(#tdate))
INSERT INTO tx_bill_pay(clid, hlid, swercharge, pay_bill, pdate, bill_id, holdingNo, holding, ClientID, ClientName, billno, date_month, bill, install, inserted_by, inserted_date)
VALUES (#clid_, #hlid_, #sr, #bill / 4, DATEADD(day, -1, DATEADD(m, 3, #tdate)), CONCAT(#holdinNo_, YEAR(#tdate), '1'), #holdinNo_, #holding_, #clientid_, #clientName_, CONCAT(#holdinNo_, YEAR#tdate)), #tdate, #bill, 1, #userid, GETDATE())
INSERT INTO tx_bill_pay(clid, hlid, swercharge, pay_bill, pdate, bill_id, holdingNo, holding, ClientID, ClientName, billno, date_month, bill, install, inserted_by, inserted_date)
VALUES (#clid_, #hlid_, 0, 2 * (#bill / 4), DATEADD(day, -1, DATEADD(m, 6, #tdate)), CONCAT(#holdinNo_, YEAR(#tdate), '2'), #holdinNo_, #holding_, #clientid_, #clientName_, CONCAT(#holdinNo_, YEAR(#tdate)), #tdate, #bill, 2, #userid, GETDATE())
SET #RowCounter_1 = #RowCounter_1 + 1
END
DROP TABLE #tempProcess_tax_1
END
New query (1-2 mins)
ALTER PROCEDURE [dbo].[process_tax]
#userid varchar(10),
#remark nvarchar(500),
#tdate date ,
#roadno nvarchar(10),
#inst int
as
BEGIN
insert into tx_bill_pay(
clid,
hlid,
swercharge,
pay_bill,
pdate,
bill_id,
holdingNo,
holding,
ClientID,
ClientName,
billno,
date_month,
bill,
install ,
inserted_by,
inserted_date)
select
cl.clid,
cl.id,
swercharge=(select case when sum(asset*rate/100) is null then 0 else
sum(asset*rate/100) end from tx_bill where hlid=cl.id and
itemID =6 and year(date_month)=YEAR(#tdate)),
pay_bill=(select case when sum(netvalue) is null then 0 else
sum(netvalue) end from tx_bill where hlid=cl.id and itemID not
in(8,6) and year(date_month)=YEAR(#tdate))/4,
DATEADD(day,-1,
DATEADD(m,3,#tdate)),
CONCAT(cl.holdinNo, year(#tdate),'1'),
cl.holdinNo,
cl.holding,
cl.ClientID,
cl.clientName,
CONCAT(cl.holdinNo,
year(#tdate)),
#tdate,
bill=(select case when sum(netvalue) is null then 0 else sum(netvalue)
end from tx_bill where hlid=cl.id and itemID not in(8,6) and
year(date_month)=YEAR(#tdate))/4,
1,
#userid, getdate()
from
(select *
from tx_holding as cl
where cl.status=1 and cl.roadno=#roadno) AS cl
INNER JOIN (
select DISTINCT hlid from tx_asset where asset is not null
) AS A
ON Cl.id = A.hlid
INNER JOIN (
select DISTINCT id from tbl_client where client_type='Non-Govt.'
) AS C
ON cl.clid=C.id
WHERE NOT EXISTS
( SELECT 1
FROM tx_bill_pay as bp
WHERE year(date_month)=year(#tdate)
and bp.hlid=cl.id
)
insert into tx_bill_pay(clid,hlid
,swercharge,pay_bill,pdate,bill_id,holdingNo,holding,ClientID,
ClientName, billno, date_month, bill, install ,inserted_by,
inserted_date)
select
cl.clid,
cl.id,
0,
pay_bill=2*((select case when sum(netvalue) is null then 0 else sum(netvalue) end from tx_bill where hlid=cl.id and itemID not in(8,6) and year(date_month)=YEAR(#tdate))/4),
DATEADD(day,-1,
DATEADD(m,3,#tdate)),
CONCAT(cl.holdinNo, year(#tdate),'2'),
cl.holdinNo,
cl.holding,
cl.ClientID,
cl.clientName,
CONCAT(cl.holdinNo, year(#tdate)) ,
#tdate,
bill=(select case when sum(netvalue) is null then 0 else sum(netvalue)
end from tx_bill where hlid=cl.id and itemID not in(8,6) and year(date_month)=YEAR(#tdate))/4,
2,
#userid, getdate()
from
(select *
from tx_holding as cl
where cl.status=1 and cl.roadno=#roadno) AS cl
INNER JOIN (
select DISTINCT hlid from tx_asset where asset is not null
) AS A
ON Cl.id = A.hlid
INNER JOIN (
select DISTINCT id from tbl_client where client_type='Non-Govt.'
) AS C
ON cl.clid=C.id
WHERE cl.id not in
( SELECT hlid
FROM tx_bill_pay
WHERE year(date_month)=year(#tdate)
and hlid is not null group by hlid
)
Great Job removing the loop!
I will point out one possible performance problem, specifically year(date_month)=year(#tdate).
Because a column is wrapped in a function, it is non-SARGABLE. This means that date_month values cannot be evaluated directly and therefore, indexes and statistics for this column cannot be used.
To resolve this I suggest the following changes:
At the top of the SP define two more variables:
DECLARE #YearStart AS DATETIME, #NextYearStart DATETIME
SET #YearStart = DATEADD(yy, DATEDIFF(yy, 0, #tdate ), 0 )
SET #NextYearStart = DATEADD( yy, #YearStart, 1 )
Then replace all instances of year(date_month)=year(#tdate) with
#YearStart <= date_month AND date_month < #NextYearStart
This above expression looks for date_month values greater than or equal to midnight (notice that time component is accounted for) of the first day of the year and less than midnight of the next year.
Next, I would look at the query plan and see if SQL Server gives a "Missing Index" recommendation (it should appear just above the plan diagram, if it does suggest an index). Try adding the recommended missing indexes, then check to see if you get a performance improvement. If you don't get an improvement, remove the index - sometimes suggestions don't help.
Updated
Having 3 sub-queries (populating columns swercharge, pay_bill, bill) using tx_bill table with different WHERE conditions will cause at least 3 evaluations of this table per one main query execution.
It may, depending on the size of the table, be more efficient to calculate all 3 sub-queries once and save results to a temp table (or a table variable) as follows:
SELECT hlid,
ISNULL( SUM( CASE WHEN itemID NOT IN (8, 6) THEN netvalue END ), 0 ) AS Bill,
ISNULL( SUM( CASE WHEN itemID = 6 THEN asset * rate / 100 END ), 0 ) AS Sr
INTO #Bills
FROM tx_bill
WHERE #YearStart <= date_month AND date_month < #NextYearStart
AND NOT hlid IS NULL
GROUP BY hlid
In your main queries, join to this table as follows:
LEFT JOIN #SumBills AS SumBills ON SumBills.hlid = cl.hlid
and in SELECT change assignments as per below example:
pay_bill= ISNULL( SumBills.Bill, 0 ) / 4,
Note: I believe you have a bug in bill column, as the value is divided by 4, where it is not in the original cursor.
The last point:
As #GarethD has said in his answer to your previous question, properly formatting your code significantly reduces the time it takes to understand and change the code. I would go one step further and say that code format represents your attitude to and understanding of the problem at hand.
I added non clustered index then my query take 5 sec to run.That's almost solve my problem. #Alex Thanks for your hard work and time. I will check your tips.I Up vote your comment

How to get columns names that been updated

Suppose I have a table like this :
Table 1:
date account name type status open_account_date
31.12.14 1000 20 40 50 31.12.14
2.1.15 1000 10 10 50 31.12.14
3.1.15 1000 5 15 50 31.12.14
and I want to build a summary table like this for the first quarter :
account numOfChanges Changes
1000 4 (name, type)
The first row in table 1 indicats that that the account was opened and somebody enterd for the account some details but the others indicats changes but i want to know which fields has been changed. Is there any suggestion or an idea how to perform this?
DECLARE #StartOfQuarter DATE = '1/1/2015'
;WITH cteRcordStateBeforeQuarter AS (
SELECT
[date]
,account
,name
,[type]
,[status]
,open_account_date
,RowNum = ROW_NUMBER() OVER (PARTITION BY account ORDER BY [date] DESC)
FROM
#Table
WHERE
[date] < #StartOfQuarter
)
, cteRecordStatesDuringQuarter AS (
SELECT
[date]
,account
,name
,[type]
,[status]
,open_account_date
,RowNum = ROW_NUMBER() OVER (PARTITION BY account ORDER BY [date] ASC) + 1
--add 1 because the first row is going to be the last one prior to quarter
,LatestChangeRowNum = ROW_NUMBER() OVER (PARTITION BY account ORDER BY [date] DESC)
FROM
#Table
WHERE
DATEPART(QQ,[date]) = 1
--change to suite ongoing needs such as quater and YEAR([date]) = ??
)
, cteRecursive AS (
SELECT
[date]
,account
,name
,[type]
,[status]
,open_account_date
,RowNum
,LatestChangeRowNum = 0
,NumOfChanges = 0
,[Changes] = CAST('' AS VARCHAR(100))
FROM
cteRcordStateBeforeQuarter
WHERE
RowNum = 1
UNION ALL
SELECT
q.[date]
,q.account
,q.name
,q.[type]
,q.[status]
,q.open_account_date
,q.RowNum
,LatestChangeRowNum = CAST(q.LatestChangeRowNum AS INT)
,NumOfChanges = r.NumOfChanges
+ CASE WHEN ISNULL(q.name,-99999) <> ISNULL(r.name,-99999) THEN 1 ELSE 0 END
+ CASE WHEN ISNULL(q.[type],-99999) <> ISNULL(r.[type],-99999) THEN 1 ELSE 0 END
+ CASE WHEN ISNULL(q.[status],-99999) <> ISNULL(r.[status],-99999) THEN 1 ELSE 0 END
+ CASE WHEN ISNULL(q.open_account_date,'1/1/1900') <> ISNULL(r.open_account_date,'1/1/1900') THEN 1 ELSE 0 END
,[Changes] = CAST(ISNULL(r.[Changes],'')
+ CASE WHEN ISNULL(q.name,-99999) <> ISNULL(r.name,-99999) AND r.[Changes] NOT LIKE '%name%' THEN ',name' ELSE '' END
+ CASE WHEN ISNULL(q.[type],-99999) <> ISNULL(r.[type],-99999) AND r.[Changes] NOT LIKE '%type%' THEN ',type' ELSE '' END
+ CASE WHEN ISNULL(q.[status],-99999) <> ISNULL(r.[status],-99999) AND r.[Changes] NOT LIKE '%status%' THEN ',status' ELSE '' END
+ CASE WHEN ISNULL(q.open_account_date,'1/1/1900') <> ISNULL(r.open_account_date,'1/1/1900') AND r.[Changes] NOT LIKE '%open_account_date%' THEN ',open_account_date' ELSE '' END
AS VARCHAR(100))
FROM
cteRecordStatesDuringQuarter q
INNER JOIN cteRecursive r
ON q.account = r.account
AND q.RowNum = r.RowNum + 1
)
SELECT
account
,NumOfChanges
,[Changes] = REPLACE(IIF(CHARINDEX(',',[Changes]) = 1, RIGHT([Changes],LEN([Changes]) - 1),[Changes]),',',', ')
FROM
cteRecursive
WHERE
LatestChangeRowNum = 1
If you where using SQL 2012 + it would be a little easier because you could use LAG or LEAD window functions and IIF instead of case. But a recursive cte works pretty well too. I assume your recordset will have multiple accounts as well as multiple quarters and there for multiple recordstates prior to the quarter. Due to this you will need to tweak the date logic slightly but this will give you the gist.
First find the record state prior to the quarter. Then find all of the changes during the quarter. Add some row numbers to determine which is the first and which is the last change. Then use a recursive cte to test for changes. In the end you just need to format the string the way you want.

SQL: LEFT OUTER JOIN not returning any rows

I have a query that is using a LEFT OUTER JOIN to merge 2 data sets. I know both data sets should return data because I ran the superquery and the subquery separately. For some reason, the query is returning zero results. Anyone know why?
Left data:
item FG_lots
447845 E2211
Right data:
candy_lot_check candy_item
L2211 835116
Intended result:
item FG_lots candy_lot_check candy_item
447845 E2211 null null
The result from my broken query (no results):
item FG_lots candy_lot_check candy_item
The query:
--Initialization--
DECLARE #Item NVARCHAR(30) = '447845'
DECLARE #Date datetime = '6/13/2016'
SET DATEFIRST 1;
DECLARE #client NVARCHAR(20)
SET #client = (SELECT i.Uf_ClientName FROM item AS i WHERE i.item = #Item)
DECLARE #count integer
--Query--
SET #count = (CASE
WHEN (#client = 'A' OR #client = 'B')
THEN 4
WHEN #client = 'C'
THEN 3
WHEN #client = 'D'
THEN 5
ELSE
4
END)
SELECT DISTINCT
t.item,
LEFT(t.lot,#count) AS FG_lots,
(CASE
WHEN candylot.candy_lots IS NULL
THEN 'NO MATCH'
ELSE candylot.candy_lots
END) AS candy_lot_check,
(CASE
WHEN candylot.item IS NULL
THEN 'NO MATCH'
ELSE candylot.item
END) AS candy_item
FROM
ISW_LPTrans AS t
LEFT OUTER JOIN
(
SELECT
t.item,
LEFT(t.lot,#count) AS candy_lots,
t.ref_num AS job,
t.ref_line_suf AS suffix
FROM
ISW_LPTrans AS t
INNER JOIN item AS i on i.item = t.item
WHERE
i.product_code = 'RM-Candy' AND
t.trans_date = #Date AND
t.trans_type = 'I' AND
t.ref_num IN
(
SELECT TOP 1
j.job
FROM
job AS j
WHERE
j.item = #Item AND
j.job_date = (SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, #Date), #Date))
ORDER BY
j.job
)
AND t.ref_line_suf IN
(
SELECT TOP 1
j.suffix
FROM
job AS j
WHERE
j.item = #Item AND
j.job_date = (SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, #Date), #Date))
)
GROUP BY
t.item,
t.lot,
t.ref_num,
t.ref_line_suf
) AS candylot ON LEFT(t.lot, #count) = candylot.candy_lots
WHERE
t.ref_num = candylot.job AND
t.ref_line_suf = candylot.suffix AND
t.trans_type = 'F' AND
t.item = #Item AND
t.trans_date = #Date
You've got two 't' aliases, try altering it.
It seems you could rewrite it to make it more readable (joinwise, not indentwise), it could be that something's not right in the logic as well

SQL query causing error due to group by statement (INVALID COLUMNS)

I have following SQL:
DECLARE #EmpId AS Varchar(20),
#CompanyId as VARCHAR(20),
#DepartmentId AS VARCHAR(20),
#DesignationId AS VARCHAR(20),
#GradeId AS VARCHAR(20),
#FromDate AS DATE,
#TillDate AS DATE
SET #EmpId = null
SET #CompanyId = NULL
SET #DepartmentId = NULL
SET #DesignationId = NULL
SET #GradeId = NULL
SET #FromDate = '1-1-2015'
SET #TillDate = '1-1-2016'
SELECT
LA.EmpId,AT.IsPaid AS 'IsPaid',
AT.AttendanceTypeCode,
(SELECT DISTINCT IsPaid
FROM LeaveApproval
WHERE empid = LA.EmpId) AS 'testPAID',
SUM(CASE WHEN AT.IsPaid = 1 THEN 1 END) AS Paid,
COUNT(CASE WHEN AT.IsPaid = 0 THEN AT.AttendanceTypeCode END) AS UnPaid,
COUNT(AT.AttendanceTypeCode) AS LeaveCount
FROM
LeaveApproval LA
INNER JOIN
AttendanceTypes AT ON LA.AttendanceTypeId = AT.AttendanceTypeId
INNER JOIN
EmpMaster EM ON LA.Empid = EM.EmpId
WHERE
EM.ActiveInActive <> 1 AND
EM.EmpId = CASE WHEN ISNULL(#EmpId ,'-1') <> '-1' AND #EmpId <> ''
THEN #EmpId
ELSE EM.EmpId
END
AND EM.CompanyId = CASE WHEN ISNULL(#CompanyId ,'-1') <> '-1' AND #CompanyId <> ''
THEN #CompanyId
ELSE EM.CompanyId
END
AND EM.DepartmentId = CASE WHEN ISNULL(#DepartmentId,'-1') <> '-1' AND #DepartmentId<> ''
THEN #DepartmentId
ELSE EM.DepartmentId
END
AND ISNULL(EM.DesignationId, '') = CASE WHEN ISNULL(#DesignationId ,'-1') <> '-1' AND #DesignationId <> '' THEN #DesignationId ELSE ISNULL(EM .DesignationId,'') END
AND ISNULL(EM.GradeId,'') = CASE WHEN ISNULL(#GradeId ,'-1') <> '-1' AND #GradeId <> '' THEN #GradeId ELSE ISNULL(EM .GradeId,'') END
AND FromDate BETWEEN #FromDate AND #TillDate
GROUP BY
LA.EmpID, AT.AttendanceTypeCode, AT.IsPaid, Paid, UnPaid
The above SQL is not working.
I get an error
Column Paid and InPaid are invalid.
What I know is that 'Paid' and Unpaid are from subquery and are NOT available in select list's group by.
My question is how can I achieve the above outcome after running my SQL my outcome should repeat same value which is sum for Paid for each empid
Any help will be appreciated
You cannot use an alias of a column of the current SELECT in its GROUP BY. You have to either do this:
Group By LA.EmpID,AT.AttendanceTypeCode,AT.IsPaid,SUM(CASE WHEN AT.IsPaid=1 Then 1 END), COUNT(CASE WHEN AT.IsPaid=0 Then AT.AttendanceTypeCode END)
Or use all your SELECT as a subquery and group by as you planned in the outer query.
DECLARE #EmpId AS Varchar(20),
#CompanyId as VARCHAR(20),
#DepartmentId AS VARCHAR(20),
#DesignationId AS VARCHAR(20),
#GradeId AS VARCHAR(20),
#FromDate AS DATE,
#TillDate AS DATE
Set #EmpId=null
SET #CompanyId= NULL
SET #DepartmentId=NULL
SET #DesignationId=NULL
SET #GradeId=NULL
SET #FromDate='1-1-2015'
SET #TillDate='1-1-2016';
with LeaveApprovalCTE as
(
Select
AT.IsPaid as 'IsPaid',
AT.AttendanceTypeCode, (select distinct IsPaid from LeaveApproval where empid=LA.EmpId) as 'testPAID',
CASE WHEN AT.IsPaid=1 Then 1 END as Paid,
CASE WHEN AT.IsPaid=0 Then AT.AttendanceTypeCode END as UnPaid,
AT.AttendanceTypeCode AS LeaveCount
From
LeaveApproval LA
INNER JOIN AttendanceTypes AT ON LA.AttendanceTypeId = AT.AttendanceTypeId
INNER JOIN EmpMaster EM ON LA.Empid = EM.EmpId
WHERE
EM.ActiveInActive <> 1 AND
EM.EmpId = CASE WHEN ISNULL(#EmpId ,'-1') <> '-1' AND #EmpId <> '' THEN #EmpId ELSE EM .EmpId END
AND
EM.CompanyId = CASE WHEN ISNULL(#CompanyId ,'-1') <> '-1' AND #CompanyId <> '' THEN #CompanyId ELSE EM .CompanyId END
AND
EM.DepartmentId = CASE WHEN ISNULL(#DepartmentId,'-1') <> '-1' AND #DepartmentId<> '' THEN #DepartmentId ELSE EM .DepartmentId END
AND
ISNULL(EM.DesignationId,'') = CASE WHEN ISNULL(#DesignationId ,'-1') <> '-1' AND #DesignationId <> '' THEN #DesignationId ELSE ISNULL(EM .DesignationId,'') END
AND
ISNULL(EM.GradeId,'') = CASE WHEN ISNULL(#GradeId ,'-1') <> '-1' AND #GradeId <> '' THEN #GradeId ELSE ISNULL(EM .GradeId,'') END
AND
FromDate BETWEEN #FromDate AND #TillDate
)
Select
AttendanceTypeCode,
SUM(Paid) as paid ,
COUNT(UnPaid) as unpaid,
COUNT(LeaveCount) AS LeaveCount
from LeaveApprovalCTE
Group By AttendanceTypeCode,IsPaid,Paid,UnPaid
Use CTE for add new columns in query . Modify your query like this . hope it will work for you

SQL Conversion failed when converting row number

So I've been trying to add an Dynamic Row Number column with out using Dynamic SQL. However when I try I get an error 'Conversion failed when converting character string to smalldatetime data type.'
I Know the Error is coming from in the functions So if you want to just look at the switch case in the function that is the problem, but here is the stored procedure just in case you need to see it.
I have a store procedure which looks like this:
ALTER PROCEDURE [dbo].[MMS_EdgateMainQueue]
-- Add the parameters for the stored procedure here
#OrderByColumnID int = 3,
#Skip int = 0,
#Take int = 0,
#Descending bit = 1,
#ResultCount INT OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Declare #UrlTitlePrefix varchar(2080) = '<a href="/Title/PageByExtTitleID?ActionName=Edgate&ExtTitleID='
Declare #UrlProducerPrefix varchar(2080) = '<a href="/Producers/ByExtVendorID?ActionName=Details&ExtVendorID='
Declare #Urlmidfix varchar(100) = '">'
Declare #UrlPostFix varchar(100) = '</a>'
SELECT TOP (#Take)
[row_numb],
#UrlTitlePrefix + ExtTitleID + #Urlmidfix + ExtTitleID + #UrlPostFix as [Item #],
f.Title as Name,
#UrlProducerPrefix + f.ExtVendorID + #Urlmidfix + f.DisplayName + #UrlPostFix as Producer,
f.Created as Created,
isnull(f.Academic, '') as Academic,
isnull(f.Sears,'') as Sears,
isnull(f.Editor, '') as Editor,
CONVERT(INT, f.[Copy]) AS Copy,
f.[Segment],
CONVERT(INT, f.[Taxonomy]) AS Taxonomy,
f.[Priority]
FROM EdgateNewTitlesInnerQuery(#OrderByColumnID, #Descending) as f
Where f.[row_numb] Between ((#Skip * #Take) + 1) and ((#Skip + 1) * #Take) order by f.[row_numb]
END
And The Inner Function Looks Like:
ALTER FUNCTION [dbo].[EdgateNewTitlesInnerQuery]
(
#OrderByColumnID int,
#Descending bit
)
RETURNS TABLE
AS
RETURN
(
SELECT DISTINCT
v.ExtVendorID,
t.ID,
t.ExtTitleID,
t.Title,
v.DisplayName,
t.Created,
ecs.Title as [Academic],
ssub.Title as [Sears],
etw.EditorName as [Editor],
etw.CopyDone AS [Copy],
etw.SegmentsStatus as [Segment],
etw.TaxonomyDone AS [Taxonomy],
CASE WHEN wft.[Priority] is null THEN 0 ELSE wft.[Priority] END as [Priority],
--row_number() OVER (ORDER BY t.Created DESC) AS [row_number]
row_number() OVER (ORDER BY
CASE #OrderByColumnID WHEN 0 THEN t.ExtTitleID
WHEN 1 THEN t.Title
WHEN 2 THEN v.DisplayName
WHEN 3 THEN t.Created
WHEN 4 THEN ecs.Title
WHEN 5 THEN ssub.Title
WHEN 6 THEN etw.EditorName
WHEN 7 THEN etw.CopyDone
WHEN 8 THEN etw.SegmentsStatus
WHEN 9 THEN etw.TaxonomyDone
WHEN 10 THEN CASE WHEN wft.[Priority] is null THEN 0 ELSE wft.[Priority] END
ELSE t.Created
END DESC ) AS [row_numb]
FROM [Title] t
join EdgateTitleWorkflow etw on etw.FK_TitleID = t.ID
join Vendor v on v.ExtVendorID = t.ProducerID
join CollectionItem i on i.TitleID = t.ID and i.CollectionID = 16
left join [EdgateSuggestedAcademicSubject] esas on esas.FK_TitleID = t.ID and esas.isPrimary = 1
left join EC_Subject ecs on ecs.ID = esas.FK_SubjectID
left join [FMGSuggestedSears] fss on fss.FK_TitleID = t.ID and fss.isPrimary = 1
left join [FMGSearsSubjects] ssub on ssub.ID = fss.SearsSubjectID and ssub.ParentID is null
left join [WorkFlow_Tracker] wft on wft.TitleID = t.ID
where (etw.CopyDone = 0 or etw.TaxonomyDone = 0 or etw.SegmentsStatus = 0)
)
I've tried passing this in as a string originally but it just didn't sort at all. So I was looking at similar problems and tried this solution Here
but my switch Case is now throwing a Conversion Error. Does anyone have an Idea on how to fix this?
The problem is that case is an expression that returns one type, defined during compilation. You can fix this with a separate case for each key. I think this is the statement you want:
row_number() OVER (ORDER BY (CASE WHEN #OrderByColumnID = 0 THEN t.ExtTitleID END),
(CASE WHEN #OrderByColumnID = 1 THEN t.Title END),
(CASE WHEN #OrderByColumnID = 2 THEN v.DisplayName END),
(CASE WHEN #OrderByColumnID = 3 THEN t.Created END),
(CASE WHEN #OrderByColumnID = 4 THEN ecs.Title END),
(CASE WHEN #OrderByColumnID = 5 THEN ssub.Title END),
(CASE WHEN #OrderByColumnID = 6 THEN etw.EditorName END),
(CASE WHEN #OrderByColumnID = 7 THEN etw.CopyDone END),
(CASE WHEN #OrderByColumnID = 8 THEN etw.SegmentsStatus END),
(CASE WHEN #OrderByColumnID = 9 THEN etw.TaxonomyDone END),
(CASE WHEN #OrderByColumnID = 10 THEN COALESCE(wft.[Priority], 0) END)
t.Created DESC
)