select every 4th saturday from a set date sql - sql-server-2008

I am trying to write a SQL statement that selects every 4th Saturday from a set date. So if the date chosen is 07/09/2014 then the query would return 05/10/2014 and 02/11/2014 and so on.
I can get it to select every Saturday going forward from the date but I can not work out how to get it to work out the 4th one each time.
SELECT DATE
, DATENAME(DW,DATE) as Date
FROM tblCalender
WHERE DATENAME(DW,DATE) = 'Saturday'
AND Date > '13-September-2014'
This is the select to get the saturdays going forward.

Sussed it thanks to t_m suggestion
DECLARE #Date DATETIME
SET #Date = '19-July-2014'
SELECT Date AS SatDate
, DayOfWeek
FROM (
SELECT DATE
, DATENAME(DW,DATE) as DayOfWeek
, ROW_NUMBER() OVER (ORDER BY Date) AS rownum
FROM tblCalender
WHERE DATENAME(DW,DATE) = 'Saturday'
AND Date > #Date
) AS t
WHERE t.rownum % 4 = 0
Thanks for the tip!

Related

Extracting year and total days between range of date - SQL

I have data with start date and end date (Say 20th Feb 2018 to 20th Feb 2020), I want to find out the total days in every year inside this range.
For example:
2018 - x days
, 2019 - 365 days
, 2020 - y days etc.
Is there a way I can do in SQL without hardcoding year values?
I tried hardcoding the values and it worked well. But I want a solution without hardcoding year values
I'm not familiar enough with MySql to know if this will port, however here is a tested and confirmed SQL Server solution.
The fiddle link is here for your use.
Given start dates 02/20/2018 and 02/20/2020, the result set is as follows:
Year
periodStart
periodEnd
DaysInPeriod
2018
2018-02-20
2018-12-31
314
2019
2019-01-01
2019-12-31
365
2020
2020-01-01
2020-02-20
51
Declare #StartDate date = '2018-02-20', #EndDate date = '2020-02-20';
WITH x AS (SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(n)),
Years AS (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS Year
FROM x ones, x tens, x hundreds, x thousands)
SELECT Years.Year,
CASE
WHEN Year(#StartDate) = Years.year THEN #StartDate
ELSE DATEFROMPARTS(years.year, 01, 01)
END AS periodStart,
CASE
WHEN Year(#EndDate) = Years.year THEN #EndDate
ELSE DATEFROMPARTS(years.year, 12, 31)
END AS periodEnd,
DATEDIFF(day,
CASE
WHEN Year(#StartDate) = Years.year THEN #StartDate
ELSE DATEFROMPARTS(years.year, 01, 01)
END,
CASE
WHEN Year(#EndDate) = Years.year THEN #EndDate
ELSE DATEFROMPARTS(years.year, 12, 31)
END
) + 1 AS DaysInPeriod
FROM Years
WHERE Years.Year >= Year(#StartDate)
AND Years.Year <= Year(#EndDate)
Using WITH RECURSIVE to create range of dates then we can easly count the number of days for each year using DATEDIFF
WITH RECURSIVE dates AS
(
SELECT min(start_date) as start_date, DATE_FORMAT(min(start_date),'%Y-12-31') as last_day FROM mytable
UNION ALL
SELECT DATE_FORMAT(start_date + INTERVAL 1 YEAR,'%Y-01-01'),
DATE_FORMAT(start_date + INTERVAL 1 YEAR,'%Y-12-31')
FROM dates
WHERE DATE_FORMAT(start_date + INTERVAL 1 YEAR,'%Y-01-01') <= (SELECT MAX(end_date) FROM mytable)
),
cte2 as (
SELECT d.start_date as start_day, if(YEAR(d.start_date) = YEAR(m.end_date), m.end_date, d.last_day) as last_day
FROM dates d, mytable m
)
select *, DATEDIFF(last_day, start_day)+1 as total_days
from cte2;
Demo here
You are looking for the DATEDIFF function.
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_datediff
DATEDIFF() returns expr1 − expr2 expressed as a value in days from one date to the other. expr1 and expr2 are date or date-and-time expressions.
You are free to specify e.g. "2019-01-01" or "2020-01-01"
as input arguments to DATEDIFF.
You may find it convenient to store several January 1st
dates in a calendar reporting table, if you want SELECT to loop
over several years and report on number of days in each year.

How do I retrieve all records between a date range and then filtered by time of day?

My dateTime column has entries like this going back months:
2019-03-11 07:00:00.000
I would like to retrieve all the data from mondays, but then further filtered by the time of day.
This is what I have so far but I dont know how to refine it any further.
WITH
cteMonday (dates1, Average) AS
(
select [Date], [High] - [Low] AS 'average'
--select *
from [Trading].[dbo].[DAX30m]
where DATEPART(dw, Date) = 2
AND [DATE] BETWEEN '2019-03-11' AND '2019-03-24'
)
select * from ctemonday
Why don't you use the DATEPART function to extend your filter criteria, e.g.:
... AND DATEPART(hh, Date) > lowerLimit AND DATEPART(hh, Date) <
upperLimit

SQL Update multiple lines from query

I have written 2 queries and I need to look at combining them, into what I think would have to be a cursor. The first query looks like this-
DECLARE #Date DATETIME
SET #Date = '12-July-2014'
SELECT Date AS SaturdayDate
, DayOfWeek
FROM (
SELECT DATE
, DATENAME(DW,DATE) as DayOfWeek
, ROW_NUMBER() OVER (ORDER BY Date) AS rownum
FROM tblCalender
WHERE DATENAME(DW,DATE) = 'Saturday'
AND Date > #Date
) AS t
WHERE t.rownum % 4 = 0
AND DATEPART(YEAR, Date) = DATEPART(Year, GETDATE())
returns every 4th Saturday for the rest of the year past the 12th July -
SaturdayDate |DayOfWeek
2014-08-09 00:00:00.000 |Saturday
2014-09-06 00:00:00.000 |Saturday
2014-10-04 00:00:00.000 |Saturday
2014-11-01 00:00:00.000 |Saturday
2014-11-29 00:00:00.000 |Saturday
2014-12-27 00:00:00.000 |Saturday
This is perfect for what I need, then i need to run an update query using the result of the above as the #SaturdayDate parameter (need it to cycle through and update every record)
UPDATE dbo.tblStaffRota
SET StartTime = '11:00:00'
WHERE (EmployeeID IN ('JJJ','HSW', 'GPH', 'DVD'))
AND (StartTime = '10:30:00')
AND (Date BETWEEN #SaturdayDate - 6 AND #SaturdayDate)
So the update query will cycle through the result of the first query updating each date with the new start time, not sure how to progress with this and all the answers I've found haven't quiet helped. Hopefully this is clear enough. Thanks
*additional note - The update needs to look at the days in the previous week to each saturday that appears and change whatever the start time is.
Sample of tables being used.
Based on this the update would change the start time on the 18th and 19th if the Saturday was in the list.
Looks like you need something like (Note: below script have not been tested) ..
Modified based on posted sample data:
DECLARE #Date DATETIME
SET #Date = '12-July-2014'
UPDATE STAFFROTA
SET StartTime = '11:00:00'
FROM dbo.tblStaffRota STAFFROTA
INNER JOIN
(
SELECT DATEADD(d, -6, Date) AS SaturdayDateStart, Date AS SaturdayDateEnd
, DayOfWeek
FROM (
SELECT DATE
, DATENAME(DW,DATE) as DayOfWeek
, ROW_NUMBER() OVER (ORDER BY Date) AS rownum
FROM tblCalender
WHERE DATENAME(DW,DATE) = 'Saturday'
AND Date > #Date
) AS t
WHERE t.rownum % 4 = 0
AND DATEPART(YEAR, Date) = DATEPART(Year, GETDATE())
) SAT
ON STARFFROTA.[Date] BETWEEN SAT.SaturdayDateStart AND SAT.SaturdayDateEnd
WHERE (STARFFROTA.EmployeeID IN ('JJJ','HSW', 'GPH', 'DVD'))
AND (STARFFROTA.StartTime = '10:30:00')

How to add hours to current date in SQL Server?

I am trying to add hours to current time like
-- NOT A VALID STATEMENT
-- SELECT GetDate(DATEADD (Day, 5, GETDATE()))
How can I get hours ahead time in SQL Server?
DATEADD (datepart , number , date )
declare #num_hours int;
set #num_hours = 5;
select dateadd(HOUR, #num_hours, getdate()) as time_added,
getdate() as curr_date
Select JoiningDate ,Dateadd (day , 30 , JoiningDate)
from Emp
Select JoiningDate ,DateAdd (month , 10 , JoiningDate)
from Emp
Select JoiningDate ,DateAdd (year , 10 , JoiningDate )
from Emp
Select DateAdd(Hour, 10 , JoiningDate )
from emp
Select dateadd (hour , 10 , getdate()), getdate()
Select dateadd (hour , 10 , joiningDate)
from Emp
Select DateAdd (Second , 120 , JoiningDate ) , JoiningDate
From EMP
The DATEADD() function adds or subtracts a specified time interval from a date.
DATEADD(datepart,number,date)
datepart(interval) can be hour, second, day, year, quarter, week etc;
number (increment int);
date(expression smalldatetime)
For example if you want to add 30 days to current date you can use something like this
select dateadd(dd, 30, getdate())
To Substract 30 days from current date
select dateadd(dd, -30, getdate())
declare #hours int = 5;
select dateadd(hour,#hours,getdate())
SELECT GETDATE() + (hours / 24.00000000000000000)
Adding to GETDATE() defaults to additional days, but it will also convert down to hours/seconds/milliseconds using decimal.
If you are using mySql or similar SQL engines then you can use the DATEADD method to add hour, date, month, year to a date.
select dateadd(hour, 5, now());
If you are using postgreSQL you can use the interval option to add values to the date.
select now() + interval '1 hour';

MySQL Query to select data from last week?

Hi I have a table with a date field and some other information.
I want to select all entries from the past week, (week start from Sunday).
table values:
id date
2 2011-05-14 09:17:25
5 2011-05-16 09:17:25
6 2011-05-17 09:17:25
8 2011-05-20 09:17:25
15 2011-05-22 09:17:25
I want to select all ids from last week, expected output is 5, 6, 8.
(id 2 not in last week, and id 15 is in current week.)
How to write and SQL Query for the same.
select id from tbname
where date between date_sub(now(),INTERVAL 1 WEEK) and now();
SELECT id FROM tbl
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
SELECT id FROM table1
WHERE YEARWEEK(date) = YEARWEEK(NOW() - INTERVAL 1 WEEK)
I use the YEARWEEK function specifically to go back to the prior whole calendar week (as opposed to 7 days before today). YEARWEEK also allows a second argument that will set the start of the week or determine how the first/last week of the year are handled. YEARWEEK lets you to keep the number of weeks to go back/forward in a single variable, and will not include the same week number from prior/future years, and it's far shorter than most of the other answers on here.
Simplified form:
Last week data:
SELECT id FROM tbl
WHERE
WEEK (date) = WEEK( current_date ) - 1 AND YEAR( date) = YEAR( current_date );
2 weeks ago data:
SELECT id FROM tbl
WHERE
WEEK (date) = WEEK( current_date ) - 2 AND YEAR( date) = YEAR( current_date );
SQL Fiddle
http://sqlfiddle.com/#!8/6fa6e/2
You can make your calculation in php and then add it to your query:
$date = date('Y-m-d H:i:s',time()-(7*86400)); // 7 days ago
$sql = "SELECT * FROM table WHERE date <='$date' ";
now this will give the date for a week ago
Probably the most simple way would be:
SELECT id
FROM table
WHERE date >= current_date - 7
For 8 days (i.e. Monday - Monday)
PLEASE people... 'Last week' like the OP asked and where I was looking for (but found none of answers satisfying) is THE LAST WEEK.
If today is Tuesday, then LAST WEEK is Monday A WEEK AGO to Sunday A WEEK AGO.
So:
WHERE
WEEK(yourdate) = WEEK(NOW()) - 1
Or for ISO weeks:
WHERE
WEEK(yourdate, 3) = WEEK(NOW(), 3) - 1
If you're looking to retrieve records within the last 7 days, you can use the snippet below:
SELECT date FROM table_name WHERE DATE(date) >= CURDATE() - INTERVAL 7 DAY;
Here is a way to get last week, month, and year records in MySQL.
Last Week
SELECT UserName, InsertTime
FROM tblaccounts
WHERE WEEK(InsertTime) = WEEK(NOW()) - 1
AND MONTH(InsertTime) = MONTH(NOW())
AND YEAR(InsertTime) = YEAR(NOW())
Last Month
SELECT UserName, InsertTime
FROM tblaccounts
WHERE MONTH(InsertTime) = MONTH(NOW()) - 1
AND YEAR(InsertTime) = YEAR(NOW())
Last YEAR
SELECT UserName, InsertTime
FROM tblaccounts
WHERE YEAR(InsertTime) = YEAR(NOW()) - 1;
You'll need to calc which day relative to today is Sunday in your middleware (php, python, etc.)*
Then,
select id
from table
where date >= "$sunday-date" + interval 7 DAY
may be a way to get sunday's date relative to today in MySQL as well; that would be arguably the cleaner solution if not too expensive to perform
It can be in a single line:
SELECT * FROM table WHERE Date BETWEEN (NOW() - INTERVAL 7 DAY) AND NOW()
A simple way can be this one, this is a real example from my code and works perfectly:
where("actions.created_at >= DATE_SUB(CURDATE(), INTERVAL 1 WEEK)")
For more example Like last month, last year, last 15 days, last 3 months
Fetch Last WEEK Record
Using the below MySQL query for fetching the last week records from the mysql database table.
SELECT name, created_at
FROM employees
WHERE
YEARWEEK(`created_at`, 1) = YEARWEEK( CURDATE() - INTERVAL 1 WEEK, 1)
The above query will not work.
After the where clause, if we can not CAST the column value, then it will not work. You should cast the column value.
e.g.:
SELECT.....
WHERE CAST( yourDateColumn AS DATE ) > DATEADD( DAY, -7, CAST( GETDATE() AS DATE )
SELECT id FROM tb1
WHERE
YEARWEEK (date) = YEARWEEK( current_date -interval 1 week )
I often do a quick "last week" check as well and the following tends to work well for me and includes today.
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = Getdate() - 7 /* Seven Days Earlier */
SET #EndDate = Getdate() /* Now */
SELECT id
FROM mytable
WHERE date BETWEEN #StartDate AND #Enddate
If you want this to NOT include today just subtract an extra day from the #EndDate. If I select these two variables today get
#StartDate 2015-11-16 16:34:05.347 /* Last Monday */
#EndDate 2015-11-23 16:34:05.347 /* This Monday */
If I wanted Sunday to Sunday I would have the following.
SET #StartDate = Getdate() - 8 /* Eight Days Earlier */
SET #EndDate = Getdate() - 1 /* Yesterday */
#StartDate 2015-11-15 16:34:05.347 /* Previous Sunday */
#EndDate 2015-11-22 16:34:05.347 /* Last Sunday */
WHERE yourDateColumn > DATEADD(DAY, -7, GETDATE()) ;
You can also use it esay way
SELECT *
FROM inventory
WHERE YEARWEEK(`modify`, 1) = YEARWEEK(CURDATE(), 1)
i Use this for the week start from SUNDAY:
SELECT id FROM tbl
WHERE
date >= curdate() - INTERVAL DAYOFWEEK(curdate())+5 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate())-2 DAY
try this
WHERE trunc(DATE) <= (trunc (sysdate) -5) AND trunc(DATE) >= (trunc (sysdate) -12)
-5 is 5 days back from system date ,, -12 is 12 days back from system date for this example wednesday / or sednesday to wednesday cant recall.
Try this:
Declare #Daytype varchar(15),
#StartDate datetime,
#EndDate datetime
set #Daytype = datename(dw, getdate())
if #Daytype= 'Monday'
begin
set #StartDate = getdate()-7
set #EndDate = getdate()-1
end
else if #Daytype = 'Tuesday'
begin
set #StartDate = getdate()-8
set #EndDate = getdate()-2
end
Else if #Daytype = 'Wednesday'
begin
set #StartDate = getdate()-9
set #EndDate = getdate()-3
end
Else if #Daytype = 'Thursday'
begin
set #StartDate = getdate()-10
set #EndDate = getdate()-4
end
Else if #Daytype = 'Friday'
begin
set #StartDate = getdate()-11
set #EndDate = getdate()-5
end
Else if #Daytype = 'Saturday'
begin
set #StartDate = getdate()-12
set #EndDate = getdate()-6
end
Else if #Daytype = 'Sunday'
begin
set #StartDate = getdate()-13
set #EndDate = getdate()-7
end
select #StartDate,#EndDate
You can try this one. it worked for me :
where date(createdtime) <= date(curdate())-7
In the the above code createdtime is database field name, as individuals this name could vary.
If you already know the dates then you can simply use between, like this:
SELECT id
FROM `Mytable`
where MyDate BETWEEN "2011-05-15" AND "2011-05-21"