find records from previous x days? - sql

How can I come up with a stored procedure that selects results for past 30 days?
where MONTH(RequestDate) > 6 and DAY(RequestDate) >= 10
and MONTH(RequestDate) < 21 and DAY(RequestDate) < 7

SELECT *
FROM Table
WHERE GETDATE() >= DATEADD(DAY, -30, GETDATE())
Substitute the first GETDATE() with the appropriate column name.
SELECT *
FROM Table
WHERE Table.ColumnName >= DATEADD(DAY, -30, GETDATE())

Are you looking for last 30 days or last month? To find start and end of each month ("generic" as your comment says), use:
select dateadd(month,datediff(month,0,getdate()),0),
dateadd(mm,datediff(mm,-1,getdate()),-1)

Something like this?
CREATE PROC GetSomeHistory
#NumDaysPrevious int
AS
BEGIN
SELECT * FROM MyTable
WHERE RequestDate BETWEEN DATEADD(dd, -1 * #NumDaysPrevious, getdate())
AND getdate();
END
......
EXEC GetSomeHistory 55;

SELECT *
FROM Table
WHERE myDate >= DATEADD(MONTH, -1, GETDATE())
doing it by month is different than doing it in 30-day blocks. Test this out as follows...
declare #mydate smalldatetime
set #mydate = '07/6/01'
select #mydate
select DATEADD(month, 2, #mydate), DATEDIFF(day, DATEADD(month, 2, #mydate), #mydate)
select DATEADD(month, 1, #mydate), DATEDIFF(day, DATEADD(month, 1, #mydate), #mydate)
select DATEADD(month, -1, #mydate), DATEDIFF(day, DATEADD(month, -1, #mydate), #mydate)
select DATEADD(month, -2, #mydate), DATEDIFF(day, DATEADD(month, -2, #mydate), #mydate)
select DATEADD(month, -3, #mydate), DATEDIFF(day, DATEADD(month, -3, #mydate), #mydate)
Here are the results:
2001-07-06 00:00:00
2001-09-06 00:00:00 | -62
2001-08-06 00:00:00 | -31
2001-06-06 00:00:00 | 30
2001-06-06 00:00:00 | 30
2001-05-06 00:00:00 | 61
2001-04-06 00:00:00 | 91

Related

SQL QUERY FROM 25(LAST MONTH) to 25(CURRENT MONTH)

I would like a query that would include from day 25 of last month to 25 of current month. Example: 25/12/2017-25/01/2018
I can't do something like transaction_date >= getdate()-31 because there are months that have 28,29 days.
Thanks!
You could use:
SELECT *
FROM your_tab
WHERE transaction_date
BETWEEN DATEFROMPARTS(IIF(MONTH(GETDATE()) = 1,YEAR(GETDATE())-1,YEAR(GETDATE())),
IIF(MONTH(GETDATE()) = 1, 12 , MONTH(GETDATE())-1)
,25)
AND DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 25);
One easy way
where
transaction_date between dateadd(dd, 25, eomonth(getdate(),-2))
and dateadd(dd, 25, eomonth(getdate(),-1))
I suggest DATEFROMPARTS to make a date with a set day, and subtract 1 month from the beginning:
WHERE [transaction_date] BETWEEN DATEADD(month, -1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 25)) AND DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 25)
You can use datetime functions to substract a month from a date:
-- Feb 2016 is 29 days
select dateadd(month, -1, '2016-01-25 00:00')
>> 2015-12-25 00:00:00.000
select dateadd(month, -1, '2016-02-25 00:00')
>> 2016-01-25 00:00:00.000
select dateadd(month, -1, '2016-03-25 00:00')
>> 2016-02-25 00:00:00.000
-- Feb 2017 is 28 days
select dateadd(month, -1, '2017-01-25 00:00')
>> 2016-12-25 00:00:00.000
select dateadd(month, -1, '2017-02-25 00:00')
>> 2017-01-25 00:00:00.000
select dateadd(month, -1, '2017-03-25 00:00')
>> 2017-02-25 00:00:00.000
declare #thatDate datetime = '2017-01-25 00:00'
select *
from ThisTable
where ThisDate between dateadd(month, -1, #thatDate) and #thatDate
If you are on mysql this might work:
SELECT *
FROM SOME_TABLE
WHERE transaction_date
BETWEEN
DATE_FORMAT(NOW(), '%Y-%m-25') - INTERVAL 1 MONTH
AND
DATE_FORMAT(NOW(), '%Y-%m-25')
You could do something along the lines of:
Select fields from table
where whateverDate > '25/12/2017' and
whateverDate < '25/01/2018'

Need to add specific time to CTE_Dates calendar

I have a Dates CTE that allows me to fill in the dates between date stamped records. (Thanks SO!) However, I need the CTE_Dates table to time stamp its "StatusDate" column with a specific time instead of '00:00:00.000' and am not quite sure how to go about ding so. Here is the CTE_Dates code:
DECLARE #StartDate date = '07/15/2017'
DECLARE #EndDate date = '07/30/2017'
;WITH cte_Dates AS
(
SELECT
CASE WHEN DATEPART(DAY, #StartDate) = 1 THEN #StartDate ELSE DATEADD(Day, DATEDIFF(Day, 1, #StartDate) + 1, 0) END AS StatusDate
UNION ALL
SELECT DATEADD(Day, 1,StatusDate)
FROM cte_Dates
WHERE DATEADD(Day, 1, StatusDate) <= #EndDate
)
--this select statement actually pulls data from 2 CTE's that are joined but represents how I am pulling the StatusDate from CTE_Dates
select
CASE WHEN CAST(statusDate as Date) IS NULL
THEN LAG(cast(StatusDate as Date)) OVER (PARTITION BY item_no ORDER BY statStart)
ELSE StatusDate END as StatusDate,
SELECT * from cte_dates
Results:
StatusDate
2017-07-15 00:00:00.000
2017-07-16 00:00:00.000
2017-07-17 00:00:00.000
2017-07-18 00:00:00.000
2017-07-19 00:00:00.000
2017-07-20 00:00:00.000
2017-07-21 00:00:00.000
2017-07-22 00:00:00.000
2017-07-23 00:00:00.000
2017-07-24 00:00:00.000
2017-07-25 00:00:00.000
2017-07-26 00:00:00.000
2017-07-27 00:00:00.000
2017-07-28 00:00:00.000
2017-07-29 00:00:00.000
2017-07-30 00:00:00.000
The CTE works great! Except I need the timestamp to be noon...
Just add time value to date like this.
DECLARE #StartDate date = '07/15/2017'
DECLARE #EndDate date = '07/30/2017'
;WITH cte_Dates AS
(
SELECT
CASE WHEN DATEPART(DAY, #StartDate) = 1 THEN #StartDate ELSE DATEADD(Day, DATEDIFF(Day, 1, #StartDate) + 1, 0) END
+ '12:00'
AS StatusDate
UNION ALL
SELECT DATEADD(Day, 1,StatusDate)
FROM cte_Dates
WHERE DATEADD(Day, 1, StatusDate) <= #EndDate
)
SELECT * FROM CTE_Dates
You could use dateadd, adding 12 hours:
SELECT DATEADD(HOUR, 12, StatusDate) AS StatusDate FROM CTE_Dates
I would just use two CTEs:
DECLARE #StartDate date = '2017-07-15';
DECLARE #EndDate date = '2017-07-30';
DECLARE #time time = '04:00:00';
WITH cte_Dates AS (
SELECT CASE WHEN DATEPART(DAY, #StartDate) = 1 THEN #StartDate ELSE DATEADD(Day, DATEDIFF(Day, 1, #StartDate) + 1, 0) END AS StatusDate
UNION ALL
SELECT DATEADD(Day, 1,StatusDate)
FROM cte_Dates
WHERE DATEADD(Day, 1, StatusDate) <= #EndDate
),
cte_DateTimes as (
select cast(statusDate as datetime) + cast(#time as datetime)
from cte_Dates
)
SELECT *
FROM CTE_DateTimes;

Get everyday of the week in SQL

i am trying to write a sql query for getting the every day of the week.
like if i run SELECT GETDATE() i am getting today'day date if run the getdate()-1 i am getting only column with yesterday date. Instead i want to get the every day in a week in different columns, someone please help with the SQL. Any help will be appreciated.
try this:
SELECT DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0) Monday,
DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0) + 1 Tuesday,
DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0) + 2 Wednsday,
DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0) + 3 Thursday,
DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0) + 4 Friday,
DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0) + 5 Saturday,
DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0) + 6 Sunday;
Does this work?
SELECT
Day1 = CAST(getdate() AS date),
Day2 = CAST(getdate()+1 AS date),
Day3 = CAST(getdate()+2 AS date),
Day4 = CAST(getdate()+3 AS date),
Day5 = CAST(getdate()+4 AS date),
Day6 = CAST(getdate()+5 AS date),
Day7 = CAST(getdate()+6 AS date);
Returns:
Day1 Day2 Day3 Day4 Day5 Day6 Day7
---------- ---------- ---------- ---------- ---------- ---------- ----------
2017-06-26 2017-06-27 2017-06-28 2017-06-29 2017-06-30 2017-07-01 2017-07-02
If this is not what you are looking for can you post what you want your query to return?

Filtering data from the previous day using DateTime values

I am trying to retrieve data for yesterday's shift using SQL Server 2008 r2.
The shift starts at 20:00 pm, and ends 10:00 am following day.
What date function can I use to retrieve data for the entire shift?
Using this:
CAST([LastStartedDate] as time)> cast('20:00' as Time)
Will only retrieve data up to midnight.
You can filter your dates with a WHERE clause that uses some date manipulation like so:
WHERE LastStartedDate >= DATEADD(HOUR, 20,
CAST(CAST(DATEADD(DAY, -1, GETDATE()) AS DATE) AS DATETIME));
This first gets yesterdays date, as a DATE so it removes the time portion:
SELECT CAST(DATEADD(DAY, -1, GETDATE()) AS DATE)
-- 2017-03-06
Then converts it back to a DATETIME to add the time as midnight of that day:
SELECT CAST(CAST(DATEADD(DAY, -1, GETDATE()) AS DATE) AS DATETIME)
-- 2017-03-06 00:00:00.000
Then it adds 20 hours to get you to 20:00 - 8.00PM:
SELECT DATEADD(HOUR, 20,CAST(CAST(DATEADD(DAY, -1, GETDATE()) AS DATE) AS DATETIME));
-- 2017-03-06 20:00:00.000
For your scenario, you need to do the same again to get the 10am cut off too and use BETWEEN.
Example:
CREATE TABLE #shift
(
LastStartedDate DATETIME ,
WorkItemsDone INT
);
INSERT INTO #shift
( LastStartedDate, WorkItemsDone )
VALUES ( DATEADD(HOUR, -18, GETDATE()), 10 ),
( DATEADD(HOUR, -15, GETDATE()), 20 ),
( DATEADD(HOUR, -14, GETDATE()), 30 ),
( DATEADD(HOUR, -10, GETDATE()), 40 ),
( DATEADD(HOUR, -5, GETDATE()), 25 ),
( DATEADD(HOUR, -2, GETDATE()), 15 ),
( DATEADD(HOUR, 4, GETDATE()), 5 ),
( DATEADD(HOUR, 10, GETDATE()), 15 );
-- all data
SELECT *
FROM #shift
-- limited data
SELECT *
FROM #shift
WHERE LastStartedDate BETWEEN
DATEADD(HOUR, 20, CAST(CAST(DATEADD(DAY, -1, GETDATE()) AS DATE) AS DATETIME))
AND DATEADD(HOUR, 10, CAST(CAST(GETDATE() AS DATE) AS DATETIME))
DROP TABLE #shift;
Produces:
-- all data
LastStartedDate WorkItemsDone
2017-03-06 16:18:04.877 10
2017-03-06 19:18:04.877 20
2017-03-06 20:18:04.877 30
2017-03-07 00:18:04.877 40
2017-03-07 05:18:04.877 25
2017-03-07 08:18:04.877 15
2017-03-07 14:18:04.877 5
2017-03-07 20:18:04.877 15
-- filtered data
LastStartedDate WorkItemsDone
2017-03-06 20:18:04.877 30
2017-03-07 00:18:04.877 40
2017-03-07 05:18:04.877 25
2017-03-07 08:18:04.877 15

displaying reporting weeks

I dont know how to loop through so that the query displays all the weeks from the reporting date?
The code determines the Mon - Sun week then should insert the values in a temp table to then query the weeks. I have hard coded the report_date and its hould display more than one record.
any ideas
DECLARE #REPORT_DATE DATETIME, #WEEK_BEGINING VARCHAR(10)
SELECT #REPORT_DATE = '2011-01-01T00:00:00'
--SELECT #REPORT_DATE = GETDATE() -- should grab the date now.
SELECT #WEEK_BEGINING = 'MONDAY'
IF #WEEK_BEGINING = 'MONDAY'
SET DATEFIRST 1
ELSE IF #WEEK_BEGINING = 'TUESDAY'
SET DATEFIRST 2
ELSE IF #WEEK_BEGINING = 'WEDNESDAY'
SET DATEFIRST 3
ELSE IF #WEEK_BEGINING = 'THURSDAY'
SET DATEFIRST 4
ELSE IF #WEEK_BEGINING = 'FRIDAY'
SET DATEFIRST 5
ELSE IF #WEEK_BEGINING = 'SATURDAY'
SET DATEFIRST 6
ELSE IF #WEEK_BEGINING = 'SUNDAY'
SET DATEFIRST 7
DECLARE #WEEK_START_DATE DATETIME, #WEEK_END_DATE DATETIME
--GET THE WEEK START DATE
SELECT #WEEK_START_DATE = #REPORT_DATE - (DATEPART(DW, #REPORT_DATE) - 1)
--GET THE WEEK END DATE
SELECT #WEEK_END_DATE = #REPORT_DATE + (7 - DATEPART(DW, #REPORT_DATE))
PRINT 'Week Start: ' + CONVERT(VARCHAR, #WEEK_START_DATE)
PRINT 'Week End: ' + CONVERT(VARCHAR, #WEEK_END_DATE)
CREATE TABLE #WeekList
(
month_date date
)
DECLARE #Interval int = 1
INSERT INTO #WeekList SELECT #WEEK_START_DATE
WHILE #Interval < 1
BEGIN
INSERT INTO #WeekList SELECT DATEADD(MONTH, - #Interval, #WEEK_START_DATE)
SET #Interval = #Interval + 1
END
SELECT
--Create the month ID code:
#WEEK_START_DATE AS Start_Week, #WEEK_END_DATE AS End_Week
FROM #WeekList
ORDER BY Start_Week DESC
DROP TABLE #WeekList
Using DATEADD and updating your #interval initialization and updated loop logic:
DECLARE #REPORT_DATE DATETIME, #WEEK_BEGINING VARCHAR(10)
SELECT #REPORT_DATE = '2011-01-01T00:00:00'
--SELECT #REPORT_DATE = GETDATE() -- should grab the date now.
SELECT #WEEK_BEGINING = 'MONDAY'
IF #WEEK_BEGINING = 'MONDAY'
SET DATEFIRST 1
ELSE IF #WEEK_BEGINING = 'TUESDAY'
SET DATEFIRST 2
ELSE IF #WEEK_BEGINING = 'WEDNESDAY'
SET DATEFIRST 3
ELSE IF #WEEK_BEGINING = 'THURSDAY'
SET DATEFIRST 4
ELSE IF #WEEK_BEGINING = 'FRIDAY'
SET DATEFIRST 5
ELSE IF #WEEK_BEGINING = 'SATURDAY'
SET DATEFIRST 6
ELSE IF #WEEK_BEGINING = 'SUNDAY'
SET DATEFIRST 7
DECLARE #WEEK_START_DATE DATETIME, #WEEK_END_DATE DATETIME
--GET THE WEEK START DATE
SELECT #WEEK_START_DATE = #REPORT_DATE - (DATEPART(DW, #REPORT_DATE) - 1)
--GET THE WEEK END DATE
SELECT #WEEK_END_DATE = #REPORT_DATE + (7 - DATEPART(DW, #REPORT_DATE))
PRINT 'Week Start: ' + CONVERT(VARCHAR, #WEEK_START_DATE)
PRINT 'Week End: ' + CONVERT(VARCHAR, #WEEK_END_DATE)
DECLARE #Interval int = datediff(WEEK,getdate(),#WEEK_START_DATE)+1
SELECT Start_Week=#WEEK_START_DATE
, End_Week=#WEEK_END_DATE
INTO #WeekList
WHILE #Interval <= 0
BEGIN
set #WEEK_START_DATE=DATEADD(WEEK,1,#WEEK_START_DATE)
set #WEEK_END_DATE=DATEADD(WEEK,1,#WEEK_END_DATE)
INSERT INTO #WeekList values (#WEEK_START_DATE,#WEEK_END_DATE)
SET #Interval += 1;
END
SELECT *
FROM #WeekList
ORDER BY Start_Week DESC
DROP TABLE #WeekList
Results (top 5 and bottom 5 of list):
Start_Week End_Week
----------------------- -----------------------
2012-03-12 00:00:00.000 2012-03-18 00:00:00.000
2012-03-05 00:00:00.000 2012-03-11 00:00:00.000
2012-02-27 00:00:00.000 2012-03-04 00:00:00.000
2012-02-20 00:00:00.000 2012-02-26 00:00:00.000
2012-02-13 00:00:00.000 2012-02-19 00:00:00.000
...
2011-01-24 00:00:00.000 2011-01-30 00:00:00.000
2011-01-17 00:00:00.000 2011-01-23 00:00:00.000
2011-01-10 00:00:00.000 2011-01-16 00:00:00.000
2011-01-03 00:00:00.000 2011-01-09 00:00:00.000
2010-12-27 00:00:00.000 2011-01-02 00:00:00.000
As an aside, you could also use the date type instead of Datetime, if you don't need to store the time.
If you would like to list the weeks and the corresponding counts or sums, you can do this as follows
Sample data
myDate
----------
2012-03-15
2012-03-15
2012-03-15
2012-03-14
2012-03-14
2012-03-14
2012-03-14
2012-03-09
2012-03-09
2012-03-09
2012-03-08
2012-03-08
2012-03-08
2012-03-01
2012-03-01
2012-03-01
2012-03-01
2012-02-29
2012-02-29
2012-02-29
2012-02-29
2012-02-23
2012-02-23
2012-02-23
2012-02-22
2012-02-22
2012-02-22
2012-02-22
Script for sample data
create table #myTable(mydate Date)
insert into #myTable select DATEADD(day, -1, getdate())
insert into #myTable select DATEADD(day, -1, getdate())
insert into #myTable select DATEADD(day, -1, getdate())
insert into #myTable select DATEADD(day, -2, getdate())
insert into #myTable select DATEADD(day, -2, getdate())
insert into #myTable select DATEADD(day, -2, getdate())
insert into #myTable select DATEADD(day, -2, getdate())
insert into #myTable select DATEADD(day, -7, getdate())
insert into #myTable select DATEADD(day, -7, getdate())
insert into #myTable select DATEADD(day, -7, getdate())
insert into #myTable select DATEADD(day, -8, getdate())
insert into #myTable select DATEADD(day, -8, getdate())
insert into #myTable select DATEADD(day, -8, getdate())
insert into #myTable select DATEADD(day, -15, getdate())
insert into #myTable select DATEADD(day, -15, getdate())
insert into #myTable select DATEADD(day, -15, getdate())
insert into #myTable select DATEADD(day, -15, getdate())
insert into #myTable select DATEADD(day, -16, getdate())
insert into #myTable select DATEADD(day, -16, getdate())
insert into #myTable select DATEADD(day, -16, getdate())
insert into #myTable select DATEADD(day, -16, getdate())
insert into #myTable select DATEADD(day, -22, getdate())
insert into #myTable select DATEADD(day, -22, getdate())
insert into #myTable select DATEADD(day, -22, getdate())
insert into #myTable select DATEADD(day, -23, getdate())
insert into #myTable select DATEADD(day, -23, getdate())
insert into #myTable select DATEADD(day, -23, getdate())
insert into #myTable select DATEADD(day, -23, getdate())
Expected Result
Count WeekStart WeekEnd
----- ---------- ----------
7 2012-02-20 2012-02-24
8 2012-02-27 2012-03-02
6 2012-03-05 2012-03-09
7 2012-03-12 2012-03-16
How to do
SET DATEFIRST 1
SELECT
COUNT(*) [Count],
DATEADD(DD, -(DATEPART(DW, mydate)-1), mydate) [WeekStart],
DATEADD(DD, 7-(DATEPART(DW, mydate)+2), mydate) [WeekEnd]
FROM
#myTable
WHERE
DATEPART(dw, mydate) >= 1 AND DATEPART(dw, mydate) <= 5 -- only weekdays
GROUP BY
DATEADD(DD, -(DATEPART(DW, mydate)-1), mydate),
DATEADD(DD, 7-(DATEPART(DW, mydate)+2), mydate)
ORDER BY
DATEADD(DD, -(DATEPART(DW, mydate)-1), mydate)