I am trying to write a SQL Server stored procedure that basically returns a derived value from an outcome of a function call. The derived field returns the difference in days and if the difference is less than 24 hours then returns hours. It is working as desired but just need to ensure if the approach is right.
Stored procedure query:
SELECT ua.ID AS UserAgreementID
, A.ID AS AgreementID
, A.Code
, A.ComplianceCode
, A.Name
, A.Description
, A.Version
, ua.UserAgreementStateID
, uas.Name AS UserAgreementStateName
, ua.AcceptanceWindowExpiry
, declaration.GetDifferenceInDaysOrHours(ua.AcceptanceWindowExpiry) AS NoOfDays
, A.Data
, pa.ID AS AuthoredByID
, pa.FirstName + ' ' + pa.LastName AS AuthoredByName
, A.Authored
, ia.ID AS IssuedByID
, ia.FirstName + ' ' + pa.LastName AS IssuedByName
, A.Issued
FROM declaration.Agreement AS A
INNER JOIN declaration.UserAgreement AS ua
ON A.ID = ua.AgreementID
INNER JOIN declaration.UserAgreementState AS uas
ON ua.UserAgreementStateID = uas.ID
LEFT JOIN common.Person AS pa
ON A.AuthoredBy = pa.ID
LEFT JOIN common.Person AS ia
ON A.IssuedBy = ia.ID
WHERE ua.UserID = 607
AND uas.Code IN ('ISS', 'DEF') -- Issued, Deferred
AND A.Draft = CONVERT(BIT, 0) -- Not a draft.
AND A.Deleted = CONVERT(BIT, 0) -- Not deleted.
AND ISNULL(A.Issued, '9999-12-31') <= GETUTCDATE() -- Issued date less than equal to today's date (Issued date).
AND ISNULL(A.Expires, '9999-12-31') > GETUTCDATE()
I have tried writing a function and not sure if it is correctly written. How do I call this function from within the query
CREATE FUNCTION declaration.GetDifferenceInDaysOrHours(#AcceptanceWindowExpiry datetime)
RETURNS int
AS
BEGIN
DECLARE #timeDifferenceInDays INT;
DECLARE #timeDifferenceInHours INT;
DECLARE #timeDifference INT;
SELECT #timeDifferenceInDays = DATEDIFF(d, GETUTCDATE(), #AcceptanceWindowExpiry)
IF #timeDifferenceInDays > 1
BEGIN
SELECT #timeDifference = #timeDifferenceInDays
END
ELSE
BEGIN
SELECT #timeDifferenceInHours = DATEDIFF(HOUR, GETUTCDATE(), #AcceptanceWindowExpiry)
IF #timeDifferenceInHours >= 0 AND #timeDifferenceInHours <= 24
BEGIN
SELECT #timeDifference = #timeDifferenceInHours
END
ELSE
BEGIN
SELECT #timeDifference = -1
END
END
RETURN #timeDifference;
END;
Related
The literature says that the declare statement is not compatible with creating a View. How do I get around it?
My declare statement looks like:
DECLARE #risk_5 TABLE (Code VARCHAR(100));
INSERT INTO #risk_5 (Code) VALUES ('AA'),('BB'),('CC');
and is then used within a select statement:
SELECT
id,
CASE
WHEN a.[10_2_1_Country] IN (SELECT Code from #risk_5)
THEN '3'
END AS Risk_Country5
FROM x
The recommendation is to pack the declare into a CTE or a stored procedure.
With both these recommendations though, I do not understand how to connect the two? What am I missing?
If you need to use variable try to use stored procedures, if you write a select query in the stored procedure you can get the data too. And you can use declare inside.
I use this way in my solution e.g.
CREATE PROCEDURE [dbo].[GetLoadSiteMass]( #month INT,
#year int,
#storageId int,
#parent nvarchar(50),
#materialSourceId nvarchar(100),
#complexIds nvarchar(50))
AS
BEGIN
DECLARE #MonthPrev int
DECLARE #YearPrev int
SET #MonthPrev = CASE WHEN #Month = 1 THEN 12 ELSE #Month - 1 END
SET #YearPrev = CASE WHEN #Month = 1 THEN #Year - 1 ELSE #Year END
declare #WagonLoadSiteId int
set #WagonLoadSiteId = (select top 1 CarriageLoadSiteId from CarriageLoadSite where LoadSiteType = 2);
DECLARE #loadSide nvarchar(10), #result decimal(18,3)
SET #loadSide=cast( #storageId as nvarchar(50));
WITH CarriageLoadSiteTreeView (
[CarriageLoadSiteId],RootId,RootName,[Code], Name, ParentID, [LoadSiteType],IsDelete,
CodeSAP,DepartmentId, Capacity, MinLimit, MaxLimit, LoadSitePlaceTypeId) AS
(
SELECT [CarriageLoadSiteId],
[CarriageLoadSiteId] RootId,
Name RootName,
[Code],
Name,
ParentID,
[LoadSiteType],
[IsDelete],
CodeSAP,
DepartmentId,
Capacity,
MinLimit,
MaxLimit,
LoadSitePlaceTypeId
FROM CarriageLoadSite WITH(NOLOCK)
WHERE ISNULL(ParentID,0) =isnull(#storageId,0) AND Isdelete!=1
UNION ALL
SELECT d.[CarriageLoadSiteId],
q.RootId RootId,
RootName RootName,
d.[Code],
d.Name,
d.ParentID,
d.[LoadSiteType],
d.[IsDelete],
d.CodeSAP,
d.DepartmentId,
d.Capacity,
d.MinLimit,
d.MaxLimit,
d.LoadSitePlaceTypeId
FROM CarriageLoadSite AS d WITH(NOLOCK)
INNER JOIN CarriageLoadSiteTreeView AS q ON d.ParentID = q.[CarriageLoadSiteId] WHERE d.IsDelete!=1
)
SELECT
ComplexId,
RootId Id,
cast(RootId as nvarchar(8))+'|Sclad'+IIF(RootId=max(R.CarriageLoadSiteId),'|finish','') [Uid],
RootName CarriageLoadSiteName,
ROUND(SUM(AMOUNT-movement-consumption)/1000,3) Amount,
cast(1 as bit) hasChildren,
T.FullPathId Path,
UparentId=IIF(#parent is null,'',#parent),
[Type]=0,
Petal = IIF(RootId=max(R.CarriageLoadSiteId),'|Sclad|finish','')
FROM (
SELECT
RootId
,RootName
,t.CarriageLoadSiteId
,t.MaterialId
,YEAR(t.Period) [Year]
,MONTH(t.Period) [Month]
,round( case when (t.Amount=0 or t.Amount is null) and (tt.Type=0 or [TypeAmountCarriage]=1 )then carr.[CertifNetto]else t.Amount end ,0 )[Amount]
,t.UnitId
, CarriageId
, tt.TurnoverTypeId
,round(dbo.GetMovementByTurnOverWithTempValue(t.turnoverid),5) movement
,dbo.GetConsumptionByTurnOver(t.turnoverid) consumption
,0 stockBegin
,round(t.Amount,0 ) CommingAmount
,case when (t.Amount=0 or t.Amount is null) and tt.Type=0 then 1 else 0 end [IsNotConfirmed]
,[TypeAmountCarriage]
,M.ComplexId
FROM Turnover t WITH(NOLOCK)
INNER JOIN TurnoverType tt ON tt.TurnoverTypeId = t.TurnoverTypeId
INNER JOIN CarriageLoadSiteTreeView l ON l.CarriageLoadSiteId = t.CarriageLoadSiteId
INNER JOIN [Carriages] carr on carr.[CarriagesID]=t.[CarriageId]
INNER JOIN Material M on M.MaterialID=t.MaterialId
WHERE YEAR(t.Period) = #Year AND
MONTH(t.Period) = #Month AND
l.LoadSiteType = 0 AND
tt.type in (0,5,4) AND
isclear=0 AND
M.MaterialSourceID in (select value from string_split(#materialSourceId, ','))
UNION ALL
SELECT RootId
,RootName
,s.CarriageLoadSiteId
,s.MaterialId
,#Year [Year]
,#Month [Month]
,round(s.Amount,0)
,s.UnitId
,CarriageId
,[TurnoverTypeId]
,round(dbo.GetMovementByStock(s.StockId),5) movement
,dbo.GetConsumptionByStock(s.StockId) consumption
,round(s.Amount,0)-s.spendStock
,0
,0 [IsNotConfirmed]
,[TypeAmountCarriage]
,M.ComplexId
FROM Stock s
INNER JOIN CarriageLoadSiteTreeView l ON l.CarriageLoadSiteId = s.CarriageLoadSiteId
INNER JOIN Material M on M.MaterialID=s.MaterialId
WHERE s.[Year] = #YearPrev AND
s.[Month] = #MonthPrev AND
s.[Type] = 0 AND
l.LoadSiteType = 0 AND
amount >0 AND
isclear=0 AND
M.MaterialSourceID in (select value from string_split(#materialSourceId, ','))
) as R
INNER JOIN CariageLoadSiteTree T on T.CarriageLoadSiteId=RootId
INNER JOIN string_split(#complexIds, ',') MM ON CAST(MM.value AS int) = R.ComplexId
WHERE AMOUNT-movement-consumption>10
GROUP BY RootName,RootId,ComplexId, T.FullPathId
ORDER BY RootName
I have this cross apply query and I want to sum the result of it
CROSS APPLY
(SELECT
SUM(CASE WHEN [day] BETWEEN #FirstDay AND #LastDay
THEN 1 ELSE 0
END) AS UsedDays
FROM
Calendar c
WHERE
([day] >= r.[DateFrom]
AND [day] <= r.[DateTo]
AND [WorkDay] = 1)) calculateUsedDays
I have a request table that contains different requests from different people
and my point is to sum all of the days from the requests from a person.
The cross apply returns the sum of the days by every request from the requests table for every person.
For example:
person
John, usedDays - 5
John, - 7
Peter - 10
Peter - 5
..
And I want to sum these days and group by name of the person so that I can have all of the days by person.
Example:
John - 12
Peter - 15
I tried with sum and group by , but it returns error:
Each GROUP BY expression must contain at least one column that is not an outer reference
Thank you :))
Thank you guys,
I solved this, but now my problem is: Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this query.
This is my code
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [core].[ReportBalanceYearSearch]
#Year int = NULL,
#TypeOfLeaveGid int = NULL,
#IsActive int = NULL
AS
BEGIN
SET NOCOUNT ON
DECLARE #Err int
DECLARE #sql nvarchar (max), #paramlist nvarchar(max)
DECLARE #FirstDay datetime
DECLARE #LastDay datetime
DECLARE #typeLeaveGid INT, #typeCreditGid INT, #relLeaveToCreditGid INT
SET #FirstDay = DATEFROMPARTS ( #Year, 1, 1)
SET #LastDay = DATEFROMPARTS ( #Year, 12, 31)
SELECT #typeLeaveGid = gid FROM Nomenclature WHERE type = 'RequestType' and Code = 1
SELECT #typeCreditGid = gid FROM Nomenclature WHERE type = 'RequestType' and Code = 2
SELECT #relLeaveToCreditGid = gid FROM Nomenclature WHERE type = 'Relation' and Code = 6
SELECT #sql = '
SELECT u.[Name],
u.[DepartmentGid],
sum(calculateUsedDays.UsedDays - isnull(calculateCreditDays.CreditDaysInPeriod,0)) as [UsedDays],
ub.[Balance],
sum(calculateUsedDays.UsedDays - isnull(calculateCreditDays.CreditDaysInPeriod,0)) + ub.[Balance] as [TotalDaysInYear],
r.[LeaveTypeGid]
FROM [dbo].[Request] r
inner join [User] u on r.[UserGid] = u.[Gid]
inner join [UserBalance] ub on r.[UserGid] = ub.UserGid and ub.Year = #xYear
LEFT OUTER JOIN dbo.Request CRD
inner join Relations rel ON rel.RelID2 = CRD.Gid AND rel.RelType = #xrelLeaveToCreditGid
inner join Nomenclature nsc ON nsc.Gid = CRD.StatusGid
cross apply (SELECT
sum(case when [day] between COALESCE(#xFirstDay, [day]) AND COALESCE(#xLastDay, [day]) then 1 else 0 end) as CreditDaysInPeriod
FROM Calendar c
WHERE [day] >= crd.[DateFrom] AND [day] <= crd.[DateTo] AND [WorkDay] = 1 ) calculateCreditDays
ON rel.RelID1 = r.Gid
and CRD.TypeGid = #xtypeCreditGid
cross apply (SELECT
sum(case when [day] between #xFirstDay and #xLastDay then 1 else 0 end) as UsedDays
FROM Calendar c
WHERE ([day] >= r.[DateFrom] AND [day] <= r.[DateTo] AND [WorkDay] = 1))calculateUsedDays
where #xYear = DATEPART(year,r.[DateFrom]) and r.TypeGid = #xtypeLeaveGid and #xIsActive IS NULL OR u.[Active] = #xIsActive
group by u.[Name], u.[DepartmentGid],r.[LeaveTypeGid], ub.[Balance]'
SELECT #paramlist ='
#xTypeOfLeaveGid int,
#xFirstDay datetime,
#xYear int,
#xLastDay datetime,
#xtypeLeaveGid int,
#xrelLeaveToCreditGid int,
#xtypeCreditGid int,
#xIsActive bit'
EXEC sys.sp_executesql #sql, #paramlist,
#TypeOfLeaveGid,
#Year,
#IsActive,
#typeLeaveGid,
#relLeaveToCreditGid,
#typeCreditGid,
#FirstDay,
#LastDay
SET #Err = ##Error
RETURN #Err
END
I'm making a stored procedure to know the future dates in which a maintenance should be scheduled, but there are a lot of machines on the table but procedure only calls one.
The Declares that I used are for it to call the data of each machine and do the cycle to know the future dates in the range given
#name varchar(50),
#FechaHasta datetime,
#Result DATETIME = null OUTPUT)
AS
BEGIN
DECLARE #JOBNO NVARCHAR(50)
SELECT #JOBNO = JOBNO FROM PMMASTER INNER JOIN LABORMP
ON PMMASTER.PMID = LABORMP.PMID INNER JOIN PMMSCHEDULE
ON PMMASTER.PMID = PMMSCHEDULE.PMID
where EMPLOYEENAME = #name AND PMMSCHEDULE.CYCLETYPE =2 and PMMSCHEDULE.SETTING2 IS NOT NULL and PMMSCHEDULE.SETTING1 IS NOT NULL
DECLARE #DATELAST DATETIME
SELECT #DATELAST = DATELAST FROM PMMSCHEDULE INNER JOIN PMMASTER
ON PMMASTER.PMID = PMMSCHEDULE.PMID INNER JOIN LABORMP
ON PMMASTER.PMID = LABORMP.PMID
WHERE JOBNO in (#JOBNO) and EMPLOYEENAME =#name
DECLARE #SETTING1 INT
SELECT #SETTING1 = SETTING1 FROM PMMSCHEDULE INNER JOIN PMMASTER
ON PMMASTER.PMID = PMMSCHEDULE.PMID INNER JOIN LABORMP
ON PMMASTER.PMID = LABORMP.PMID
WHERE JOBNO in (#JOBNO) AND EMPLOYEENAME = #name
DECLARE #SETTING2 INT
SELECT #SETTING2 = SETTING2 FROM PMMSCHEDULE INNER JOIN PMMASTER
ON PMMASTER.PMID = PMMSCHEDULE.PMID INNER JOIN LABORMP
ON PMMASTER.PMID = LABORMP.PMID
WHERE JOBNO in (#JOBNO) AND EMPLOYEENAME = #name
DECLARE
#DateFirst INT
SELECT #DateFirst = ##DateFirst
/* Today */
DECLARE
#TodaysDate DATETIME
-- Finding today's date after resetting the time to midnight
SELECT #TodaysDate = CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE(), 101), 101)
/* Todays WeekDay */
DECLARE
#TodaysWeekDay INT
SELECT #TodaysWeekDay = DATEPART(dw, #TodaysDate)
/* Selected WeekDay */
DECLARE
#WeekDay INT
SELECT #WeekDay = CHARINDEX('1', #Setting2)
/* Schedule Date */
DECLARE
#ScheduleDate DATETIME
-- Find the starting schedule date. If the schedule date is in a previous
-- week, adjust to the most recent week in the schedule
SELECT #ScheduleDate = #DATELAST
-- Adjust scheduled date to closest possible week day
SELECT #ScheduleDate = DATEADD(dd, #WeekDay - DATEPART(dw, #ScheduleDate), #ScheduleDate)
-- Add cycles until a possible date is met
WHILE (#ScheduleDate < #TodaysDate)
SELECT #ScheduleDate = DATEADD(wk, #Setting1, #ScheduleDate)
IF (#ScheduleDate <= #DATELAST)
SELECT #ScheduleDate = DATEADD(wk, #Setting1, #ScheduleDate)
SELECT #Result = #ScheduleDate
SELECT #Result AS RESULTADO
SET DATEFIRST #DateFirst
WHILE(#Result <#FechaHasta)
BEGIN
IF(#Result <#FechaHasta)
SELECT #Result = DATEADD(WK, #Setting1, #Result)
SET IDENTITY_INSERT [00TblFecha] ON
INSERT INTO dbo.[00TblFecha](idFecha,jobno,fecha)VALUES(3,#JOBNO,#Result)
SET IDENTITY_INSERT[00TblFecha] OFF
print #Result
end
You have few options: - Use table valued parameter, which is preferable: (https://msdn.microsoft.com/en-us/library/bb510489.aspx) - Use XML parameter - Use comma delimited list. - Do the loop over all of your "machines"
By the way, exclude usage of ##DateFirst in your SP. Anyway you do not use it.
We have a procedure that uses the below While..Loop to calculate the total number of Days and Weeks paid for absences in our PayRoll System:
EDITED
Declare #Absences Table (slno int identity (1,1),AbsenceId int, ToDate datetime)
INSERT INTO #Absences (AbsenceID,ToDate)
Select AbsenceID, AB.ToDate
from t_Absence AB with (nolock)
Inner Join t_AbsenceCategory AB_CAT with (nolock) ON (AB.AbsenceCategoryID = AB_CAT.AbsenceCategoryID)
where (AB_CAT.IsSSP =1)
and ClientID = #ClientID
and AB.FromDate >= #SSPYearStart --D7830 SJH 21/10/2015
order BY AB.ToDate desc
Declare #AbsenceID INT, #iCtr INT, #maxRows int
Declare #FromDate datetime
SELECT #iCtr = 1, #maxRows = MAX(slno) FROM #Absences
Select #SSPDaysPaid = 0, #SSPweeksPaid = 0, #QualifyingDaysInWeek = 0
If IsNull(#maxRows,0) > 0 select #FromDate = FromDate from t_Absence where AbsenceID = (SELECT AbsenceID FROM #Absences WHERE slno = 1)
WHILE ( #ictr <= #maxRows )
BEGIN
SELECT #AbsenceID = AbsenceID
FROM #Absences
WHERE slno = #iCtr
--Print #AbsenceID
If Exists (Select TOP 1 1 from t_Absence where ToDate > DATEADD(dd,-56, #FromDate))
BEGIN
SELECT #SSPDaysPaid = #SSPDaysPaid + IsNull(A.SSPDays,0),
#FromDate = A.FromDate
from t_Absence A
where A.AbsenceID = #AbsenceID
print '#SSPDaysPaid=' + CAST(#SSPDaysPaid AS Varchar(3)) + ' in Absence ' + cast(#AbsenceID as varchar(6))
DECLARE #Monday int, #Tuesday int, #Wednesday int, #Thursday int, #Friday int, #Saturday int, #Sunday int
SELECT #Monday = QD.Monday, #Tuesday = QD.Tuesday, #Wednesday =QD.Wednesday, #Thursday =QD.Thursday,
#Friday = QD.Friday, #Saturday = QD.Saturday, #Sunday = QD.Sunday
from t_PayrollEmployeeSSPQualifyingDays QD
inner JOIN t_Absence A on A.ClientID = QD.ClientID and A.FromDate = QD.DateFrom AND A.ToDate = QD.DateTo
where A.ClientID = #ClientId
SET #QualifyingDaysInWeek = #Monday + #Tuesday + #Wednesday + #Thursday + #Friday + #Saturday + #Sunday
print '#QualifyingDaysInWeek = ' + cast(#QualifyingDaysInWeek as char(2))
END
SET #iCtr = #iCtr + 1
END
if #QualifyingDaysInWeek <> 0 Set #SSPWeeksPaid = #SSPDaysPaid/#QualifyingDaysInWeek Else Set #SSPWeeksPaid = 0
print '#SSPWeeksPaid=' + cast(#SSPWeeksPaid as varchar(2))
Select
BradfordFactor
, CSPFDEntitlement
, CSPHDEntitlement
, CSPDaysTaken
, HasContract
, CSPFullDaysTaken
, CSPHalfDaysTaken -- DevTask 112703 06/11/2012 SWB Start
, IsNull(#SSPDaysPaid,0) as 'SSPDaysPaid'
, IsNull(#SSPWeeksPaid,0) as 'SSPWeeksPaid'
from
fn_GetEmployeeBradfordFactor(#ClientID,DEFAULT,0, DEFAULT)
END
As I need to find out this information for several different persons I will have to execute this stored proc and loop once for each client Id (#ClientId) identified in the calling procedure ...
Is there an alternative to this loop and would it be worth it in terms of performance?
Based on the OP comment, no other value is needed from the loop, but #QualifyingDaysInWeek
#RicardoC : Well I don't need the prints (they're there for debugging and analysis) but I do need to sum the values #QualifyingDaysInWeek in for each record in the table #Absences
There appears to be no need for the loop at all.
Declare #Absences Table (slno int identity (1,1),AbsenceId int, ToDate datetime)
INSERT INTO #Absences (AbsenceID,ToDate)
Select AbsenceID, AB.ToDate
from t_Absence AB with (nolock)
Inner Join t_AbsenceCategory AB_CAT with (nolock) ON (AB.AbsenceCategoryID = AB_CAT.AbsenceCategoryID)
where (AB_CAT.IsSSP =1)
and ClientID = #ClientID
and AB.FromDate >= #SSPYearStart --D7830 SJH 21/10/2015
order BY AB.ToDate desc
DECLARE #QualifyingDaysInWeek INT
SELECT #QualifyingDaysInWeek = SUM(QD.Monday + QD.Tuesday + QD.Wednesday + QD.Thursday + QD.Friday + QD.Saturday + QD.Sunday)
FROM t_PayrollEmployeeSSPQualifyingDays QD
INNER JOIN t_Absence A ON A.ClientID = QD.ClientID
AND A.FromDate = QD.DateFrom
AND A.ToDate = QD.DateTo
WHERE A.ClientID = #ClientId;
What I am doing is using own function, which is returning string, now I want this column for ordering, and while using it for ordering it is not ordering properly because its a string, when I tried to convert as datetime it causes an error.
Any help ?
Thanks a lot.
SELECT
b.CallId,
CONVERT(VARCHAR(25), b.ETADate, 103) as'ETADate',
dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId) AS 'closingDateTime'
FROM
CallEntry AS a, CallEntrySerialNumbers AS b
WHERE
a.ASPId = 2
AND a.CompanyId = 3
AND a.CallId= b.CallId
AND a.ProdCompanyId = 1
AND b.CallCaseId IS NOT NULL
AND b.CallCaseId NOT LIKE 'NA'
AND ProdCategoryid = 1
AND a.CallDateTime > dateadd(day, -30, getdate())
AND b.StatusId = 2
ORDER BY
dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId) ASC
// what I tried and causes above error is
ORDER BY
CONVERT(DATE, dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId)) asc
EDIT-added function
ALTER FUNCTION [dbo].[ASP_getCallEntrySerialNoLastTranDateTime]
(
#CallEntrySerialNumbersId bigint
)
RETURNS varchar(500)
AS
BEGIN
DECLARE #ReturnVal NVARCHAR(500);
begin
select #ReturnVal = ( select Top 1 CONCAT(CONVERT(VARCHAR(10),CallTranEndDateTime,103),' ',CONVERT(VARCHAR(10),CallTranEndDateTime,108)) from calltransactions
where CallEntrySerialNumbersId = #CallEntrySerialNumbersId AND CallTranTypeId = 3
order by CallTranId desc)
end;
RETURN #ReturnVal;
END
Try this one -
SET DATEFORMAT dmy
SELECT *
FROM (
SELECT
b.CallId
, ETADate = CONVERT(VARCHAR(25), b.ETADate, 103)
, closingDateTime = dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId)
FROM dbo.CallEntry a
JOIN dbo.CallEntrySerialNumbers b ON a.CallId = b.CallId
WHERE a.ASPId = 2
AND a.CompanyId = 3
AND a.ProdCompanyId = 1
AND ISNULL(b.CallCaseId, '') NOT LIKE 'NA'
AND ProdCategoryid = 1
AND a.CallDateTime > DATEADD(day, -30, GETDATE())
AND b.StatusId = 2
) d
ORDER BY CAST(d.closingDateTime AS DATE)
ALTER FUNCTION [dbo].[ASP_getCallEntrySerialNoLastTranDateTime]
(
#CallEntrySerialNumbersId BIGINT
)
RETURNS VARCHAR(30)
AS BEGIN
DECLARE #ReturnVal VARCHAR(30)
SELECT #ReturnVal = (
SELECT TOP 1 CONVERT(VARCHAR(10), CallTranEndDateTime, 103) + ' ' + CONVERT(VARCHAR(10), CallTranEndDateTime, 108)
FROM dbo.CallTransactions
WHERE CallEntrySerialNumbersId = #CallEntrySerialNumbersId
AND CallTranTypeId = 3
ORDER BY CallTranId DESC
)
RETURN #ReturnVal
END