How do I select birthdays in the next 30 Days - sql

I have a table with birthdates and I want to select all the birthdays that will come in the next 30 days.
The situation is, that all the birthdays are written in the form off 1999-09-15 which means that even if I tried selecting the next 30 days, the birthdays wouldn't show up because the year is 1999.
I am running Microsoft Server 2016.
SELECT * from dbo.EMPLOYEES
WHERE DATE <= DATEADD(day, +30,GETDATE())
and DATE >= getdate()
order by "DATE"

To get the birthdate, we need to work only on the days and the months, not on the year. Thats why we cannot get Where date between 2 dates.
SELECT
dateofbirth_c AS BIRTHDAY
,FLOOR(DATEDIFF(dd,EMP.dateofbirth_c,GETDATE()) / 365.25) AS AGE_NOW
,FLOOR(DATEDIFF(dd,EMP.dateofbirth_c,GETDATE()+30) / 365.25) AS AGE_30_Days_FROM_NOW
FROM
Employees EMP
WHERE 1 = (FLOOR(DATEDIFF(dd,EMP.dateofbirth_c,GETDATE()+30) / 365.25))
-
(FLOOR(DATEDIFF(dd,EMP.dateofbirth_c,GETDATE()) / 365.25))

Try the following; check the month and day because year will not match with birthday year that's why you are not getting any data.
SELECT *
from dbo.EMPLOYEES
WHERE month(DATE)>= month(GETDATE())
and day(DATE) >= day (getdate()) and day(DATE) < = day( getdate()) + 30
order by "DATE"

I'm note sure about microsoft server but on postgres just generate list of days and compare like this.
SELECT * FROM table WHERE to_char(user_dob, 'MM-DD') IN
(SELECT to_char(date, 'MM-DD')
FROM generate_series(current_date, current_date + 30, '1 day') AS date);
And now all you have to change that 30 to any days to make it work.

try this
SELECT *
FROM dbo.EMPLOYEES
WHERE DATEFROMPARTS(YEAR(GETDATE()) , MONTH(Date), DAY(Date)) >= GETDATE()
AND DATEFROMPARTS(YEAR(GETDATE()) , MONTH(Date), DAY(Date)) <= DATEADD(day, +30, GETDATE())
ORDER BY Date

If you want an accurate result that works for leap years and so on, then:
SELECT e.*
FROM dbo.EMPLOYEES e CROSS APPLY
(VALUES (DATEFROMPARTS(YEAR(GETDATE()),
MONTH(e.date),
DAY(e.date)
)
)
) v(this_year_date)
WHERE DATEDIFF(day, GETDATE(), this_year_date) BETWEEN 0 AND 29 OR
DATEDIFF(day, GETDATE(), DATEADD(year, 1, this_year_date)) BETWEEN 0 AND 29
order by "DATE"

Related

Query to select between two dates without year

I am trying to update certain fields for employees whose date of joining falls in between 10 Jun and 31 Dec, irrespective of the year. I am trying using 'Between' Operator but it requires year to be included in the dates. Is there a way to generalise it in order to consider Day and Month excluding the Year?
Use the DatePart function - replace thedate with your column, and thetable with the column.
Something like this:
select datepart(MONTH, thedate), datepart(DAY, thedate),*
from thetable
where datepart(MONTH, thedate) between 6 and 12
and datepart(DAY, thedate) between 10 and 31
You may try this:
WITH Emp AS (
SELECT *, DATEPART(MONTH, JoinDate) AS MonthJoin, DATEPART(DAY, JoinDate) AS DayJoin
FROM Employees)
SELECT *
FROM Emp
WHERE (MonthJoin > 1 AND MonthJoin < 12)
OR (MonthJoin = 1 AND DayJoin >= 10)
OR (MonthJoin = 12 AND DayJoin <= 31)
Where Employees is your table and JoinDate is your date of joining in this table

Datepart into previous year based on week

I am learning SQL at the moment and needed a query that would return the previous 12 weeks (excluding the current week) and the below worked just fine - that was until we moved in to 2019!
My table has 4 columns, BuildWeek, BuildYear, Info1, Info2, all are int.
select *
from Dashboard
where BuildWeek in (datepart(week, getdate()) - 1,
datepart(week, getdate()) - 2,
datepart(week, getdate()) - 3,
datepart(week, getdate()) - 4,
datepart(week, getdate()) - 5,
datepart(week, getdate()) - 6,
datepart(week, getdate()) - 7,
datepart(week, getdate()) - 8,
datepart(week, getdate()) - 9,
datepart(week, getdate()) - 10,
datepart(week, getdate()) - 11,
datepart(week, getdate()) - 12,
datepart(week, getdate()) - 13)
and BuildYear = datepart(year, getdate())
order by
BuildWeek desc
I know this is not the cleanest query so I'm quite open to being educated, I have tried a few things (using dateadd to no avail) but cannot seem to get it to function how I wish. I'm guessing the above stems from the query perhaps looking into a minus (current date -1 would be 0, -2 would be -1 so no results would be found?) but I'm not sure how to make it look backwards to return those extra weeks.
Another solution would be to generate a date from BuildWeek and BuildYear (say, the first day of the week), that can be used in the WHERE clause.
The advantage with this approach is that is guaranteed to return the records of the last 12 weeks, even if there is not exactly 12 of them (for example if you have gaps in the weeks series), or if future records exist.
SELECT d.*
FROM Dashboard d
WHERE
DATEADD( wk, DATEDIFF( wk, 7, CAST( d.BuildYear AS NVARCHAR(100) ) ) + (d.BuildWeek-1) , 7 )
BETWEEN DATEADD( week, -12, GETDATE() ) AND GETDATE()
ORDER BY
d.BuildYear DESC,
d.BuildWeek DESC
Tested in this db fiddle.
Assuming you have one row per week:
select top (12) d.*
from Dashboard d
order by d.year desc, d.BuildWeek desc;
To avoid future weeks:
select top (12) d.*
from Dashboard d
where year < year(getdate()) or
(year = year(getdate()) and buildweek <= datepart(week, getdate())
order by d.year desc, d.BuildWeek desc;
Or, if you want to use a where and years have 52 weeks:
select d.*
from dashboard d
where (y.year * 52 + buildweek) >= year(getdate()) * 52 + datepart(week, getdate());
This method becomes a bit trickier if years can have 53 weeks.

Get employee with tenure of 2 to 5 years in sql

I have a tenure table where I have columns link id, name, join date of an employee.
I am trying to get only those employee whose tenure(work experience) is 2 to 5 years from join date to today's date.
I used query
SELECT ID FROM tenure WHERE DATEADD(year, 2, JoinDate) >= '2018-08-06' AND DATEADD(year, 5, JoinDate) <= '2018-08-06';
My tabular structure is
How can I get only those employees whose working period or tenure is between 2 to 5 years from their join date to today's date?
You can use TimeStampDiff() :
SELECT ID
FROM tenure t
WHERE timestampdiff(YEAR, JoinDate, now()) >= 2 AND
timestampdiff(YEAR, JoinDate, now()) <= 5;
use TIMESTAMPDIFF function
SELECT ID FROM tenure WHERE
TIMESTAMPDIFF(YEAR, date(joindate), date(now()))>= 2 and
TIMESTAMPDIFF(YEAR, date(joindate), date(now()))<=5
To me, your syntax suggests SQL Server. The logic would be:
where joindate >= dateadd(year, -5, getdate()) and
joindate < dateadd(year, -2, getdate())
Compare the Joindate to the expected range based on today's date
select *
from tenure
where joindate between DATE_ADD(cur_date(), INTERVAL -5 YEAR)
and DATE_ADD(cur_date(), INTERVAL -2 YEAR)

SQL Server 3 month from now

I need a SQL select statement to retrieve all employees that their enddate contract will end three month from now and only three month not more or less
It depends what you mean by 3 months from now. If you mean on that exact date, then:
WHERE my_date_column = cast(dateadd(month, 3, getdate()) as date)
Note the cast to date to remove the time component. This is ambiguous and under some circumstances might miss employees or count them twice.
If you want employees whose contract ends in the 3rd month from today, then use:
WHERE DATEDIFF(month, getdate(), my_date_column) = 3
So, if this is January, this will return employees whose contract ends any time in April.
SELECT *
FROM TABLE_NAME
WHERE Date_Column >= DATEADD(DAY, +90, GETDATE())
OR
SELECT *
FROM TABLE_NAME
WHERE Date_Column >= DATEADD(MONTH, +3, GETDATE())
OR
SELECT *
FROM TABLE_NAME
WHERE DATEDIFF(MONTH, my_date_column, GETDATE()) <= 3

How to group daily data on weekly basis using sql

I am trying to group the number of hours that employees worked for the last 4 weeks but I want to group them on a weekly basis. For example:
WEEK HOURS
Feb 24 to March 2 55
March 3 to March 9 40
March 10 to March 16 48
March 17 to March 23 37
This is what I have so far, please help. thanks
SET DATEFIRST 1
SELECT CAST(MIN( [DT]) AS VARCHAR(20))+' TO '+CAST (MAX([DT]) AS VARCHAR(20)) AS DATE,
SUM(HOURS) AS NUM_HRS
FROM MyTable
GROUP BY DATEPART(WEEK,[DT])
HAVING COUNT(DISTINCT[DT])=7
Create a Calendar auxilliary table, with Year, Month, Week, Date columns (you can also add holidays and other interesting stuff to it, it has many potential uses) and populate it for the period of interest.
After that, it's as easy as this:
SELECT sum(hours), cast(min(date) as varchar), cast(max(date) as varchar)
FROM Calendar c
LEFT OUTER JOIN MyTable h on h.Date = c.date
GROUP BY year, week
ORDER BY year, week
SET DATEFIRST 1
SELECT DATEPART(WEEK,DT) AS WEEK,
SUM(HOURS) AS NUM_HRS
FROM MyTable
WHERE DT >= DATEADD(WEEK, -4, GetDate()),
GROUP BY DATEPART(WEEK,[DT])
Try something like
SELECT
DATEADD(DD,
CONVERT(INT, (DATEDIFF(DD, '1/1/1900', t.DT)/7)) * 7,
'1/1/1900') [WeekBeginDate],
DATEADD(DD,
(CONVERT(INT, (DATEDIFF(DD, '1/1/1900', t.DT)/7)) * 7) + 6,
'1/1/1900') [WeekEndDate],
SUM(HOURS) AS NUM_HRS
FROM MyTable t
GROUP BY CONVERT(INT, DATEDIFF(DD, '1/1/1900', t.DT)/7)
Though this is the brute force trick, I think in your case it will work.
EDIT : Modified the query a little bit, the error was caused because of the order in which DATEDIFF calculates the difference.
Also here is a SQL FIDDLE with a working example.
EDIT 2 : Updated the Fiddle with the Date Format. To customize the date format, this article would help.