How do I determine if two leave requests (time off) conflict (overlap) - tsql

I have an HR system and I need to see if the new leave (time off) request conflicts with an existing one. I have done this based on the entire day, but I need to do the comparison based on half days...
Here is my data structure (and the data format) This is all done in SQL Server 2008 R2.
StartDate (datetime)
EndDate (datetime)
'The following 2 variables show if the user is taking a half or a full day off.
'The options for each are listed and explained.
StartDateAMPM (int) 0=All Day (StartDate may or may not be the same as the EndDate),
1=AM, (User is out of the office only in the morning)
2=PM (User is out of the office only in the afternoon)
EndDateAMPM (int) 0="All Day" / "half day" / "StartDate = EndDate",
1=AM (The user is off for the morning only)
**NOTE This cannot be PM (as you cannot end a leave
with a half day in the afternoon)
**IF this is a "0", there are 3 possibilities --
A) a full day leave where the StartDate <> EndDate
B) a full day where the StartDate = EndDate
C) a partial day where StartDate = EndDate and the user
is off in the morning or the afternoon
So I pass this info to the DB and am trying to see if the new leave conflicts with existing leave... Here is the code to do it for a single day:
Legend: #Start DateTime -- StartDate from new leave
#end DateTime -- EndDate from new leave
#StartDateAMPM (int) 0,1,2 (see above for details)
EndDateAMPM (int) 0,1 (see above for details)
select count(ID) from v_VacReqWHalfDays
where
( #Start BETWEEN StartDate and EndDate
OR #End BETWEEN StartDate and EndDate
OR (#Start <= StartDate and #End >=EndDate))
and kUserID = #UserID
If Count(ID) > 0, there is a conflict --
My question is how to incorporate the 1/2 day leave... (people can take full days or half days off (the morning or the afternoon).
I want to use TSQL to determine if the current leave request conflicts (overlaps) with an existing and can't figure out how to do it...

I realize this has been asked and answered...
Algorithm to detect overlapping periods ...
Thanks all... this is a dup question. Please disregard... I realize I should add the actual time stamp of the leave... to my Start and End Dates and do a simple compare -- I wish I had figured this out months ago... would have saved me much pain and suffering...
My new startDate will be recorded as "08/22/2015 09:00:00.000"
instead of "08/22/2015 00:00:00.000"
and the endDate will be "08/23/2015 13:00:00.000"
instead of "08/23/2015 00:00:00.000"
I can then compare as per the linked ticket:

Related

SQL - Getting day for the whole week

I want to get the whole day of the week depend on the date, my query is working and getting the result that I want but when the date value is Sunday, result changes.
I'm starting the result from Mon to Sunday.
Examples below:
My Code:
SELECT UserID,Scdl_TkIN as TimeIn, Scdl_TkOut as [TimeOut]
FROM EmployeeTimekeeping
WHERE CONVERT(DATE,Scdl_TkIN) >= dateadd(day, 2-datepart(dw, '2022-04-23'),CONVERT(date,'2022-04-23'))
AND CONVERT(DATE,Scdl_TkIN) < dateadd(day, 9-datepart(dw, '2022-04-23'), CONVERT(date,'2022-04-23'))AND UserID ='15020009'
ORDER BY CONVERT(DATE,Scdl_TkIN)
1st display is correct, but when I change the value into '2022-04-24' , the result is now the second pic but I want the result still 1st pic.
If I got it right you want the whole week of data given a single date.
I'm not 100% sure about your date logic and I'd rather use the WEEK as a filter as it seems clearer, that said the issue you have is the value of SELECT ##DATEFIRST.
By default its value is 7, meaning that Sunday is considered the first day of the week, that's why you get that "unexpected" result.
here is my solution, but just setting SET DATEFIRST 1; should give you the expected result.
SET DATEFIRST 1;
SELECT
UserID
,Scdl_TkIN as TimeIn
,Scdl_TkOut as TimeOut
FROM EmployeeTimekeeping
WHERE
DATEPART(WEEK,Scdl_TkIN) = DATEPART(WEEK,'2022-04-23')
AND YEAR(Scdl_TkIN) = YEAR('2022-04-23')
AND UserID ='15020009'
ORDER BY
Scdl_TkIN
Note: if you decide to use WEEK for filtering you will have to choose between WEEK and ISO_WEEK
Edit: when using week you must also consider the year in the filter

Tricking Weekofyear in Hive by shifting the week, for counting

I've been working on this problem for a while now. Basically I have a simple set of data with UserId, and TimeStamp. I want to know how many distinct UserId's appear each week, the catch is my week is measured in Sunday-Saturday, NOT Monday - Sunday, which is what Weekofyear() uses.
Right now I'm hardcoding each week and running the query:
SELECT
count(distinct UserId)
FROM data.table
where from_unixtime((CAST(timestamp as BIGINT)))
between TO_DATE("2016-06-05") AND TO_DATE("2016-06-12")
I'm trying to find a way to shift the timestamp back a day to trick weekofyear into thinking my Sunday is actually a Monday, but have not been successful. My latest futile attempt looked like:
SELECT
count(distinct UserId), weekofyear(date_sub(from_unixtime(CAST(timestamp as BIGINT)),1))
FROM table.data
where from_unixtime((CAST(timestamp as BIGINT)))
between TO_DATE("2016-06-01") AND TO_DATE("2016-06-30")
group by weekofyear(date_sub(from_unixtime(CAST(timestamp as BIGINT)),1))
This results in the same numbers as if I didn't subtract a day. I not sure why this isn't working. I feel like there should be a way to manage this. Right now if I wanted to pull all the data by week WHERE X is true, I'd have to manually do each week, that won't be sustainable. Any suggestions on how to work smarter?
Thank you.
Simple Solution
You can simply create your own formula instead of going with pre-defined function for "week of the year"
Advantage: you will be able to take any set of 7 days for a week.
In your case since you want the week should start from Sunday-Saturday we will just need the first date of sunday in a year
eg- In 2016, First Sunday is on '2016-01-03' which is 3rd of Jan'16
--assumption considering the timestamp column in the format 'yyyy-mm-dd'
SELECT
count(distinct UserId), lower(datediff(timestamp,'2016-01-03') / 7) + 1 as week_of_the_year
FROM table.data
where timestamp>='2016-01-03'
group by lower(datediff(timestamp,'2016-01-03') / 7) + 1;

How to get total experience in terms of date object

I have a condition here in which I will have total experience in terms of month and year. For example, two drop down will be there for asking total number of experience in month and year. So if I am working from 1 Jan 2012, then I will write total experience as 3 year and 11 months. Now I have to convert this 3 year and 11 months into date format so that I can save this into database
You could use java.util.Calendar:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, month);
calendar.add(Calendar.YEAR, year);
Date date = calendar.getTime();
As a word of caution, the day field would be set to today's date. Check the intended behaviour if the current day is outside of the bounds for the target month. For example, setting the month to February when calendar has a day field of 30. It might be wise to set the day to a known, valid value for every month (eg: 1) before setting the month and year.
Use DATE_SUB() function:
Try this:
SELECT DATE_SUB(DATE_SUB(CURRENT_DATE(), INTERVAL 3 YEAR), INTERVAL 11 MONTH);
You can use mysql's date_sub() function or <date> - interval <expression> unit syntax to subtract an interval from a date.
select date_sub(curdate(),interval '3-11' YEAR_MONTH) as start_date
UPDATE:
Following the conversation between the OP and #eggyal, the OP need to replace the period in the incoming data with - and construct an insert statement as follows:
insert into mytable (...,join_date,...) values (...,date_sub(curdate(),interval '3-11' YEAR_MONTH),...)

Between Date Time T-SQL

I have the following Where clause which is causing me issues and I am looking for a work around.
#startDate is the todays date and #endDate is the end date which could be 7 days, 14 days or 20 days in the future, this works fine unless the end month is greater than the start month.
ISSUE- if the StartDate DAY is 20 and the END Date Day is in the next Month example Start Day is 10/21 and End Day is 11/5 than the where clause cancels its self out, I can't use a Between because we are not including the yr.
I tried an OR but this also doesn't work.
WHERE DAY(t.AnniversaryDate) >= DAY(#startDate)
AND DAY(t.AnniversaryDate) <= DAY(#endDate)
AND MONTH(t.AnniversaryDate) >= MONTH(#startDate)
AND MONTH(t.AnniversaryDate) <= MONTH(#endDate)
AND YEAR(t.AnniversaryDate) < YEAR(GETDATE())
The expression
select DATEADD(year,DATEDIFF(year,'19780517',GETDATE()),'19780517')
Will always return the 17th of May of the current year. A similar expression can be used to perform the same trick for any date1 by replacing both instances of '19780517' with the date of interest.
So, whatever "I can't use a Between because we are not including the yr" means, you should be able to work around it by using the above expression.
So, I think what you want would be:
WHERE DATEADD(year,
DATEDIFF(year,t.AnniversaryDate,GETDATE()),
t.AnniversaryDate)
BETWEEN #startDate and #endDate
1So long as you're happy that 29th February maps to 28th February if you ask for it in a non-leap year.

Format Dates in Crystal report

I am new to crystal reports. I have a report on which there are two date fields : Benefit Start & Benefit End Dates.
I have to compare the age of the employees.
If age>65 years, Benefit Start date should be 20160101.
If age<65 years, Benefit Start date should be first day of the month effective.
eg: if the date is '09/21/2015', the output should be'09/01/2015'.
Similarly for benefit End Date,
If age<65 years, Benefit End date should be last day of the month effective.
eg: if the date is '09/02/2015', the output should be 09/30/2015.
How do I hard code the days in dates so that I get the first day & last day of the months for the two fields?
Please help me
Thanks in advance.
date(year({effectivedate})+1,1,1) -- returns Jan 1 of following year
date(year({effectivedate}),month({effectivedate}),1) -- returns first day of month for effective date
date(year(dateadd('m',1,{effectivedate})),month(dateadd('m',1,{effectivedate})),1)-1 -- returns last day of effective month
I hope... I didnt test
try this:
Start date:
DateSerial (YEAR(Cdate(datefield)),MONTH(Cdate(datefield)) ,1 );
End Date:
DateADD("d",-1,DateAdd ("m",1 ,Cdate(datefield) ))