Combine two select statements for date comparison - sql-server

Hi I have the following statement:
DECLARE #currentWEEK INT
DECLARE #previousWEEK INT
DECLARE #CURRENDATE DATETIME
DECLARE #PREVIOUSDATE DATETIME
SET #PREVIOUSDATE = YEAR(DATEADD(YEAR, -1, GETDATE()))
SET #CURRENDATE = GETDATE()
SET #currentWEEK = RIGHT(DATENAME(wk,'2013-05-17 00:00:00.000'),2)
SET #previousWEEK = RIGHT(DATENAME(wk,'2012-05-17 00:00:00.000'),2)
SELECT COUNT(*)
FROM vevents
WHERE RIGHT(DATENAME(wk,dbo.vEvents.DateCreated),2) = #currentWEEK
AND
YEAR(dbo.vEvents.DateCreated) = YEAR(#CURRENDATE)
SELECT COUNT(*)
FROM vevents
WHERE RIGHT(DATENAME(wk,dbo.vEvents.DateCreated),2) = #previousWEEK
AND
YEAR(dbo.vEvents.DateCreated) = #PREVIOUSDATE
Essentially it compares a total for two dates within a given week, but I would like to combine the two select statements for given dates to return a single record set(eg CURRENTYEARCOUNT AND PREVIOUSYEARCOUNT)
Many thanks for your help

Try this one -
DECLARE
#currentWEEK INT
, #previousWEEK INT
, #CURRENDATE DATETIME
, #PREVIOUSDATE DATETIME
SELECT
#PREVIOUSDATE = YEAR(DATEADD(YEAR, -1, GETDATE()))
, #CURRENDATE = GETDATE()
, #currentWEEK = RIGHT(DATENAME(wk, '20130517'), 2)
, #previousWEEK = RIGHT(DATENAME(wk, '20120517'), 2)
SELECT
COUNT(CASE WHEN YEAR(e.DateCreated) = #PREVIOUSDATE THEN 1 END)
, COUNT(CASE WHEN YEAR(e.DateCreated) = YEAR(#CURRENDATE) THEN 1 END)
FROM dbo.vEvents e
WHERE RIGHT(DATENAME(wk, e.DateCreated), 2) = #currentWEEK

Related

Get number of days,month,year from give two dates and type casting

I am trying to get the number of days,month and year from 2dates, but those are getting individual
DECLARE #datecount INT;
DECLARE #monthcount INT;
DECLARE #yearcount INT;
SELECT #datecount = (SELECT DATEDIFF(DAY, usr.registrationdate, GETDATE())
FROM users usr
WHERE usr.userid = #UserId);
SELECT #monthcount = (SELECT DATEDIFF(MONTH, usr.registrationdate, GETDATE())
FROM users usr
WHERE usr.userid = #UserId);
SELECT #yearcount = (SELECT DATEDIFF(YEAR, usr.registrationdate, GETDATE())
FROM users usr
WHERE usr.userid = #UserId);
How to cast these 3 variables? Or how can I get this in one step?
no. of days / no. of months / no. of year
What I want the output is = 3:1:2 or 3 days / 1 month / 4 years
A user-defined function can be useful for this.
Since the correct calculation for such an interval isn't as straight forward as one would assume.
The UDF below calculates the interval between 2 dates, with the output in the format of a JSON object.
CREATE FUNCTION dbo.fnGetDateInterval
(
#FromDate DATE, #ToDate DATE
)
RETURNS NVARCHAR(40)
WITH SCHEMABINDING
AS
BEGIN
DECLARE #Years INT, #Months INT, #Days INT;
DECLARE #tmpFrom DATE;
SET #Years = DATEDIFF(YEAR, #FromDate, #ToDate)
- IIF(#ToDate < DATEADD(YEAR, DATEDIFF(YEAR, #FromDate, #ToDate), #FromDate), 1, 0);
SET #tmpFrom = DATEADD(YEAR, #Years , #FromDate)
SET #Months = DATEDIFF(MONTH, #tmpFrom, #ToDate)
- IIF(#ToDate < DATEADD(MONTH,DATEDIFF(MONTH, #tmpFrom, #ToDate), #tmpFrom), 1, 0);
SET #tmpFrom = DATEADD(MONTH, #Months , #tmpFrom)
SET #Days = DATEDIFF(DAY, #tmpFrom, #ToDate)
- IIF(#ToDate < DATEADD(DAY, DATEDIFF(DAY, #tmpFrom, #ToDate), #tmpFrom), 1, 0);
RETURN CONCAT('{', '"years":', #Years,
',"months":', #Months,
',"days":', #Days, '}')
END;
DECLARE #UserId INT = 42;
SELECT CONCAT(days, ' days ', months, ' months ', years, ' years') AS DaysMonthsYears
FROM users usr
CROSS APPLY OPENJSON(dbo.fnGetDateInterval(usr.registrationdate, GETDATE()))
WITH (years INT '$.years',
months INT '$.months',
days INT '$.days') AS js
WHERE usr.userid = #UserId;
DaysMonthsYears
3 days 1 months 4 years
Test on db<>fiddle here

Deriving values from SQL query

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;

Use cross apply function

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

Using maxrecursion in INSERT query

Thank you for looking at this.
I have two CTE tables that generate duty times, the calculations are convoluted so wont bother you with them.
Here is the SQL (Simplified)
DECLARE #StartDate Datetime -- Start Date for the Duties to be generated
DECLARE #PatternStartPoint int --Start Point in Pattern eg 3 -
DECLARE #PatternSize int --The length of the shift pattern
DECLARE #User int
SET #User = 1111;
SET #PatternSize = 3;
SET #DaysRequired=16; --Testing assume 16
SET #StartDate = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())); --for testing use today
SET #PatternStartPoint =3;
--Get Job Duty Pattern
WITH Pattern (P_DayNumber, P_DayType, P_Start, P_End)
AS
(
Select D_DayNumber,D_Type,D_Start,D_End
from dbo.Tbl_Jobs as J
join dbo.Tbl_Patterns as P
on J.J_PatternID = P.Pattern_ID
join dbo.Tbl_PatternDetails as D
on P.Pattern_ID=d.D_Pattern_ID
)
,
--Get DateList
Datelist (MyDate, DayNumber) AS
(
SELECT #StartDate AS MyDate, #PatternStartPoint as DayNumber
UNION ALL
Select MyDate + 1, (DayNumber+1) - (CAST((Daynumber+1)/(#PatternSize+.01) as int)*#PatternSize) --% (#PatternSize)
FROM Datelist
WHERE MyDate < (#Startdate + #DaysRequired)-1
)
INSERT INTO [IDAHO].[dbo].[Appointments]
([Subject]
,[Description]
,[Start]
,[End]
,[RoomID]
,[UserID]
)
(
SELECT
'Standard Work Pattern'
,'IDAHO Generated on ' + CONVERT(nvarchar(20),getdate())
,mydate + p.P_Start
,mydate + p.P_End
,1
,#User as A_User
FROM Datelist as d
join Pattern as p
on p.P_DayNumber=d.DayNumber
Where mydate + p.P_Start is not null
OPTION (MAXRECURSION 0)
)
I am getting an error with the MAXRECURSION line, if I remove the line and try to generate more than 100 'Duties' it errors (being the default value).
If I Change the last statement to a simple select it seems to work??? as shown below
DECLARE #StartDate Datetime -- Start Date for the Duties to be generated
DECLARE #PatternStartPoint int --Start Point in Pattern eg 3 -
DECLARE #PatternSize int --The length of the shift pattern
DECLARE #DaysRequired int --The length of the shift pattern
DECLARE #User int
SET #User=1111;
SET #PatternSize = 3;
SET #DaysRequired=160; --Testing assume 16
SET #StartDate = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())); --for testing use today
SET #PatternStartPoint =3;
--Get Job Duty Pattern
WITH Pattern (P_DayNumber, P_DayType, P_Start, P_End)
AS
(
Select D_DayNumber,D_Type,D_Start,D_End
from dbo.Tbl_Jobs as J
join dbo.Tbl_Patterns as P
on J.J_PatternID = P.Pattern_ID
join dbo.Tbl_PatternDetails as D
on P.Pattern_ID=d.D_Pattern_ID
)
,
--Get DateList
Datelist (MyDate, DayNumber) AS
(
SELECT #StartDate AS MyDate, #PatternStartPoint as DayNumber
UNION ALL
Select MyDate + 1, (DayNumber+1) - (CAST((Daynumber+1)/(#PatternSize+.01) as int)*#PatternSize) --% (#PatternSize)
FROM Datelist
WHERE MyDate < (#Startdate + #DaysRequired)-1
)
SELECT
'Standard Work Pattern'
,'IDAHO Generated on ' + CONVERT(nvarchar(20),getdate())
,mydate + p.P_Start
,mydate + p.P_End
,1
,#User as A_User
FROM Datelist as d
join Pattern as p
on p.P_DayNumber=d.DayNumber
Where mydate + p.P_Start is not null
OPTION (MAXRECURSION 0)
Have I put the command in the wrong place?
Why does it work with select but not insert?
Thank you
I think its because the CTE doesn't finally get assembled into a result set until the final select is run, which is why tour second query works. To make the insert work, try:
DECLARE #StartDate Datetime -- Start Date for the Duties to be generated
DECLARE #PatternStartPoint int --Start Point in Pattern eg 3 -
DECLARE #PatternSize int --The length of the shift pattern
DECLARE #DaysRequired int --The length of the shift pattern
DECLARE #User int
SET #User=1111;
SET #PatternSize = 3;
SET #DaysRequired=160; --Testing assume 16
SET #StartDate = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())); --for testing use today
SET #PatternStartPoint =3;
--Get Job Duty Pattern
INSERT INTO [IDAHO].[dbo].[Appointments]
([Subject]
,[Description]
,[Start]
,[End]
,[RoomID]
,[UserID]
)
select *
from
(
SELECT
'Standard Work Pattern' [Subject]
,'IDAHO Generated on ' + CONVERT(nvarchar(20),getdate()) [Description]
,mydate + p.P_Start [Start]
,mydate + p.P_End [End]
,1 [RoomID]
,#User [UserID]
FROM
(
SELECT #StartDate AS MyDate, #PatternStartPoint as DayNumber
UNION ALL
Select MyDate + 1, (DayNumber+1) - (CAST((Daynumber+1)/(#PatternSize+.01) as int)*#PatternSize) --% (#PatternSize)
FROM Datelist
WHERE MyDate < (#Startdate + #DaysRequired)-1
) as d
join
(
Select D_DayNumber,D_Type,D_Start,D_End
from dbo.Tbl_Jobs as J
join dbo.Tbl_Patterns as P
on J.J_PatternID = P.Pattern_ID
join dbo.Tbl_PatternDetails as D
on P.Pattern_ID=d.D_Pattern_ID
) as p
on p.P_DayNumber=d.DayNumber
Where mydate + p.P_Start is not null
) x;
That might work.
(Expanded as requested)
(Amended to remove CTEs)

Conversion failed when converting date and/or time from character string

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

Resources