I want to fetch missing dates between two dates
say #maxDate = '2013-01-28'
say #curDate = GetDate()
I have written CTE to do this. Here is my CTE:
create procedure EmpDate
as begin
declare #curDate Date
set #curDate = GETDATE()
declare #maxDate Date
select #maxDate = MAX(EmpAttendance.Sdate)
from EmpAttendance
;with GetDates As
(
select 1 as counter, #maxDate as Date
UNION ALL
select counter + 1, DATEADD(day,counter,#maxDate)
from GetDates
where DATEADD(day, counter, #maxDate) < #curDate
)
select Date from GetDates
end
go
The result of this is
Date
2013-01-28
2013-01-29
2013-01-30
but I want
2013-01-29
2013-01-30
Please help me out.
Change
select 1 as counter, #maxDate as Date
to
select 1 as counter, DATEADD(day,1,#maxDate) as Date
To make it simpler though change the CTE
;with GetDates As
(
select DATEADD(day,1,#maxDate) as TheDate
UNION ALL
select DATEADD(day,1, TheDate) from GetDates
where TheDate < #curDate
)
...
DECLARE #STARTDATE DATETIME;
DECLARE #ENDDATE DATETIME;
DECLARE #YEARS INTEGER;
SET #YEARS = 10;
SET #STARTDATE = '20170101';
SELECT #ENDDATE = DATEADD(DAY,-1,DATEADD(YEAR,#YEARS,#STARTDATE));
DECLARE #FirstDayOfWeek INTEGER;
SET #FirstDayOfWeek = 6;
;WITH CTE_DATES
AS
(
SELECT #STARTDATE AS [DATE],
1 AS [Level]
UNION ALL
SELECT
DATEADD(DAY,1, [DATE] ) , [Level] + 1
FROM CTE_DATES
WHERE [DATE] < #ENDDATE
)
SELECT
[DATE],
DATENAME(dw,[Date]) AS Daynamelong,
LEFT(DATENAME(dw,[Date]),3) AS DaynameShort,
DATEPART(dw,[Date]) AS NaturalDayNumber,
CASE WHEN DATEPART(dw,[Date]) >= #FirstDayOfWeek THEN (DATEPART(dw,[Date]) - (#FirstDayOfWeek)) +1
ELSE
((DATEPART(dw,[Date]) - (#FirstDayOfWeek)) +1) + 7
END AS SpecialDayNumber,
[Level]
FROM
CTE_DATES
ORDER BY
[DATE] ASC
OPTION (MAXRECURSION 5000);
Related
I would like to get date range from week number in sql.
eg .
select datepart(week,GETDATE()) // 37
I want to get dates from week 37(4/09/2016 , 05/09/2016 , 06/09/2016 , 07/09/2016 , 08/09/2016 , 09/09/2016 , 10/09/2016)
Try this,
DECLARE #StartDate DATE = dateadd(day, 1-datepart(dw, getdate()), CONVERT(date,getdate()))
, #EndDate DATE = dateadd(day, 7-datepart(dw, getdate()), CONVERT(date,getdate()))
SELECT DATEADD(DAY, nbr - 1, #StartDate) as CurrentWeekDates
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
FROM sys.columns c
) nbrs
WHERE nbr - 1 <= DATEDIFF(DAY, #StartDate, #EndDate)
I have this tiny table with just "fecha" field in it.
I need a MySQL query that inserts every sunday and saturday of the year to the table.
My own research got me to the point where i know i need to do something like this:
DECLARE diaRecorrido date();
SET diaRecorrido = date(now());
WHILE DATEPART(WEEKDAY,diaRecorrido) = 1 or DATEPART(WEEKDAY,diaRecorrido) = 7
BEGIN
INSERT INTO feriados (fecha)
VALUES (diaRecorrido)
IF diaRecorrido=2017/01/01
THEN
LEAVE lazo;
END IF;
END;
Any guidance is much apreciated!
I think, you should use DAYOFWEEK()
create PROCEDURE generateSundayAndSaturday()
BEGIN
DECLARE _now DATETIME;
DECLARE _endYear DATETIME;
SET _endYear = DATE_FORMAT(NOW() + INTERVAL 1 YEAR ,'%Y-01-01');
SELECT now() into _now from dual;
while _now < _endYear DO
if DAYOFWEEK(_now) = 7 THEN -- Saturday
-- insert into
SET _now = _now + INTERVAL 1 DAY;
ELSEIF DAYOFWEEK(_now) = 1 THEN -- Sunday
-- insert into
SET _now = _now + INTERVAL 6 DAY;
ELSE
SET _now = _now + INTERVAL 1 DAY;
END IF;
END WHILE;
END;
You could create a numbers table and then select from it the days of the year which you wish to keep:
DECLARE #Date1 DATE, #Date2 DATE
SET #Date1 = '20160101'
SET #Date2 = '20161231'
INSERT INTO feriados
SELECT DATEADD(DAY,number+1,#Date1) [Date]
FROM master..spt_values
WHERE type = 'P' AND
DATEADD(DAY,number+1,#Date1) < #Date2 AND
(DATEPART(WEEKDAY, DATEADD(DAY,number+1,#Date1)) = 1 OR
DATEPART(WEEKDAY, DATEADD(DAY,number+1,#Date1)) = 7)
This is MS SQL (t-sql) query. I think you can fix small syntax differences for MySQL.
declare #thisYear datetime=cast(year(getdate()) as varchar)+'-01-01',
#newyear datetime=cast(year(getdate())+1 as varchar)+'-01-01'
declare #frstSat datetime, #frstSun datetime
select #frstSat= dateadd(dd,7-DATEPART(weekday,#thisYear),#thisYear) ,
#frstSun= case DATEPART(weekday,#thisYear)
when 1 then #thisYear --if 1/1 is Sunday
else dateadd(dd,8-DATEPART(weekday,#thisYear),#thisYear) end
;with sat as (
select #frstSat dt,'Sat' WkDay
union all
select dateadd(dd,7,dt),'Sat' WkDay
from sat
where dateadd(dd,7,dt)<#newyear
)
,sun as (
select #frstSun dt,'Sun' WkDay
union all
select dateadd(dd,7,dt),'Sun' WkDay
from sun
where dateadd(dd,7,dt)<#newyear
)
--insert mytable
select * from sat
union
select * from sun
order by dt
I have a table in a MySQL database with a field of the type date. Herein the birthday of a user is stored. Is there a pure SQL way to select the age in years from the field?
Try like this...
SELECT
id,
Name,
DateofBirth,
((DATEDIFF(Cast((Select Now()) as Date),
Cast(DateofBirth as Date)))/365) AS DiffDate
from TABEL1
Edit Considereing Fact from Transact Charlie....
SELECT
id,
Name,
DateofBirth,
TIMESTAMPDIFF(Year, Cast(DateofBirth as Date),
Cast((Select Now()) as Date)) AS DiffDate
from TABEL1
Stored Proc example:
DATEDIFF(datepart, startdate, enddate)
Easier:
-- Declare Two DateTime Variable
Declare #Date1 datetime
Declare #Date2 datetime
-- Set #Date1 with Current Date
set #Date1 = (SELECT GETDATE());
-- Set #Date2 with 5 days more than #Date1
set #Date2 = (SELECT DATEADD(day, 5,#Date1 ))
-- Get The Date Difference
SELECT DATEDIFF(day, #Date1, #Date2) AS DifferenceOfDay
I have got the code in this site for all weeks in a year as follows,i should populate week dates, starting date as saturday and end date as friday. when the week is finished it should enter to the next week with dates.
how could i achieve this please help me.
DECLARE #Year INT=2013;
DECLARE #start DATE;
--DECLARE #WK INT=2
SET #start = DATEADD(YEAR, #Year-1900, 0);
;WITH n AS
(
SELECT TOP (366) -- in case of leap year
TDate = DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY name)-1, #start)
FROM sys.all_objects
),
x AS
(
SELECT md = MIN(TDate) FROM n
WHERE DATEPART(WEEKDAY, TDate) = 7 -- assuming DATEFIRST is SATURDAY
),
y(TDate,wk) AS
(
SELECT n.TDate, ((DATEPART(DAYOFYEAR,n.TDate)-
DATEDIFF(DAY, #start,x.md)-1)/7)+1
FROM n CROSS JOIN x
WHERE n.TDate >= x.md
AND n.TDate < DATEADD(YEAR, 1, #start)
)
SELECT [date] = TDate, [week] = wk
FROM y WHERE wk < 53
ORDER BY [date];
Not really sure what you're asking, but based on your query above this will give week numbers, based on Saturday being the first day of the week, for 2013:
DECLARE #Year INT=2013;
DECLARE #start DATE;
SET #start = DATEADD(YEAR, #Year-1900, 0);
SET DATEFIRST 6; -- Set start of week as Saturday
WITH n AS
(
SELECT TOP (366) -- in case of leap year
TDate = DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY name)-1, #start)
FROM sys.all_objects
)
select TDate
, DATEPART(WEEK,TDate)
from n
where year(TDate) = 2013;
Edit:
So based on the various comments and answers I think what is required here is, for a given day, return all days in that same week, with Saturday as the first day of the week. So something like this:
set datefirst 6; -- make sure first day of week is Saturday
declare #date date = getdate(); -- change date as required here
with daysOfWeek as
(
select [date] = dateadd(dd, -datepart(dw, #date) + 1, #date)
union all
select [date] = dateadd(dd, 1, [date])
from daysOfWeek
where [date] < dateadd(dd, -datepart(dw, #date) + 7, #date)
)
select [date], dayOfWeek = datename(dw, [date])
from daysOfWeek
Which gives results:
I think this is what's required here?
Second edit:
First, create the function:
create function dbo.weekDates (#date date)
returns #dates table ([date] date, [dayofweek] varchar(9))
as
begin
with daysOfWeek as
(
select [date] = dateadd(dd, -datepart(dw, #date) + 1, #date)
union all
select [date] = dateadd(dd, 1, [date])
from daysOfWeek
where [date] < dateadd(dd, -datepart(dw, #date) + 7, #date)
)
insert into #dates ([date], [dayofweek])
select [date], [dayOfWeek] = datename(dw, [date])
from daysOfWeek;
return
end
go
Using the function:
set datefirst 6 -- Set Saturday as first day of week
select * from dbo.weekDates (getdate()) -- Change input parameter as required
I HAVE ACHIEVED TO DISPLAY THE WEEK DATES BUT IT IS DISPLAYING THE NEXT WEEK DATES I WANT TO DISPLAY THE CURRENT WEEK DATES, HERE START DAY IS SATURDAY AND END DAY IS FRIDAY
ALTER FUNCTION GetCurrentWeek()
RETURNS #TWeek TABLE (TWeek NVARCHAR(20))
AS
BEGIN
DECLARE #Year INT= DATEPART(YEAR,GETDATE());
DECLARE #start DATE;
SET #start = DATEADD(YEAR, #Year-1900, 0);
;WITH n AS
(
SELECT TOP (366) -- in case of leap year
TDate = DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY name)-1, #start)
FROM sys.all_objects
),
x AS
(
SELECT md = MIN(TDate) FROM n
WHERE DATEPART(WEEKDAY, TDate) = 7 -- assuming DATEFIRST is SATURDAY
),
y(TDate,wk) AS
(
SELECT n.TDate, ((DATEPART(DAYOFYEAR, n.TDate)
- DATEDIFF(DAY, #start, x.md)-1)/7) + 1
FROM n CROSS JOIN x
WHERE n.TDate >= x.md
AND n.TDate < DATEADD(YEAR, 1, #start)
)
INSERT #TWeek
SELECT [date] = TDate
FROM y WHERE wk =DATEPART(wk, GetDate())
ORDER BY [date];
RETURN;
END
I need to calculate the difference (in days) between two dates in MySQL excluding weekends (Saturday and Sunday). That is, the difference in days minus the number of Saturday and Sunday in between.
At the moment, I simply count the days using:
SELECT DATEDIFF('2012-03-18', '2012-03-01')
This return 17, but I want to exclude weekends, so I want 12 (because the 3rd and 4th, 10th and 11th and 17th are weekends days).
I do not know where to start. I know about the WEEKDAY() function and all related ones, but I do not know how to use them in this context.
Simply try it using a simple function :
CREATE FUNCTION TOTAL_WEEKDAYS(date1 DATE, date2 DATE)
RETURNS INT
RETURN ABS(DATEDIFF(date2, date1)) + 1
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7);
Test :
SELECT TOTAL_WEEKDAYS('2013-08-03', '2013-08-21') weekdays1,
TOTAL_WEEKDAYS('2013-08-21', '2013-08-03') weekdays2;
Result :
| WEEKDAYS1 | WEEKDAYS2 |
-------------------------
| 13 | 13 |
Illustration:
mtwtfSSmtwtfSS
123456712345 one week plus 5 days, you can remove whole weeks safely
12345------- you can analyze partial week's days at start date
-------12345 or at ( end date - partial days )
Pseudocode:
#S = start date
#E = end date, not inclusive
#full_weeks = floor( ( #E-#S ) / 7)
#days = (#E-#S) - #full_weeks*7 OR (#E-#S) % 7
SELECT
#full_weeks*5 -- not saturday+sunday
+IF( #days >= 1 AND weekday( S+0 )<=4, 1, 0 )
+IF( #days >= 2 AND weekday( S+1 )<=4, 1, 0 )
+IF( #days >= 3 AND weekday( S+2 )<=4, 1, 0 )
+IF( #days >= 4 AND weekday( S+3 )<=4, 1, 0 )
+IF( #days >= 5 AND weekday( S+4 )<=4, 1, 0 )
+IF( #days >= 6 AND weekday( S+5 )<=4, 1, 0 )
-- days always less than 7 days
Below function will give you the Weekdays, Weekends, Date difference with proper results:
You can call the below function like,
select getWorkingday('2014-04-01','2014-05-05','day_diffs');
select getWorkingday('2014-04-01','2014-05-05','work_days');
select getWorkingday('2014-04-01','2014-05-05','weekend_days');
DROP FUNCTION IF EXISTS PREPROCESSOR.getWorkingday;
CREATE FUNCTION PREPROCESSOR.`getWorkingday`(d1 datetime,d2 datetime, retType varchar(20)) RETURNS varchar(255) CHARSET utf8
BEGIN
DECLARE dow1, dow2,daydiff,workdays, weekenddays, retdays,hourdiff INT;
declare newstrt_dt datetime;
SELECT dd.iDiff, dd.iDiff - dd.iWeekEndDays AS iWorkDays, dd.iWeekEndDays into daydiff, workdays, weekenddays
FROM (
SELECT
dd.iDiff,
((dd.iWeeks * 2) +
IF(dd.iSatDiff >= 0 AND dd.iSatDiff < dd.iDays, 1, 0) +
IF (dd.iSunDiff >= 0 AND dd.iSunDiff < dd.iDays, 1, 0)) AS iWeekEndDays
FROM (
SELECT dd.iDiff, FLOOR(dd.iDiff / 7) AS iWeeks, dd.iDiff % 7 iDays, 5 - dd.iStartDay AS iSatDiff, 6 - dd.iStartDay AS iSunDiff
FROM (
SELECT
1 + DATEDIFF(d2, d1) AS iDiff,
WEEKDAY(d1) AS iStartDay
) AS dd
) AS dd
) AS dd ;
if(retType = 'day_diffs') then
set retdays = daydiff;
elseif(retType = 'work_days') then
set retdays = workdays;
elseif(retType = 'weekend_days') then
set retdays = weekenddays;
end if;
RETURN retdays;
END;
Thank You.
Vinod Cyriac.
Bangalore
IT my helpful to you
The bellow logic only show the how many days
like
sun mon
1 2 .....................
DELIMITER $$
DROP FUNCTION IF EXISTS `xx`.`get_weekday` $$
CREATE FUNCTION `xx`.`get_weekday` (first_date date, last_date date, curr_week_day int) RETURNS INT
BEGIN
DECLARE days_tot int;
DECLARE whole_weeks int;
DECLARE first_day int;
DECLARE last_day int;
SET whole_weeks = FLOOR(DATEDIFF(last_date,first_date)/7) ;
SET first_day = WEEKDAY(first_date) ;
SET last_day = WEEKDAY(last_date) ;
IF curr_week_day BETWEEN first_day AND last_day
AND last_day > first_day
OR ( curr_week_day BETWEEN last_day AND first_day
AND last_day < first_day )
THEN SET days_tot = whole_weeks + 1;
ELSE SET days_tot = whole_weeks ;
END IF;
RETURN days_tot;
END $$
DELIMITER ;
SELECT
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 0) as mo,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 1) as tu,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 2) as we,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 3) as th,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 4) as fr,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 5) as sa,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 6) as su;
Table based query
ip:
Weekday count
2 10
3 5
SELECT WEEKDAY( `req_date_time` ) AS weekday, COUNT( id ) AS id
FROM `ddd`
WHERE (
`req_date_time` >= '2014-12-01'
AND `req_date_time` <= '2014-12-31'
)
AND WEEKDAY( `req_date_time` ) != '1'
GROUP BY WEEKDAY( `req_date_time` )
You can use a dates table:
tbl_dates
dow is 'day of week' in my table. Then your query looks like this:
SELECT Count(theDate) AS numWeekDays
FROM tbl_dates
WHERE theDate >[startDate] And theDate <=[endDate] AND dow <> 1 AND dow <> 7;
In this case, 1 and 7 are Sunday, Saturday, respectively (which is the default) and, of course, you can nest that into another query if you need to calculate this for many startDate(s) and endDate(s).