Okay, I'll simplify this post.
I have a table "tasks" containing, for example, a task name, the date it starts, and a frequency. Based on these fields I need to be able to specify a date range and return each occurrence of that task for when it's due. For example, if I have a task with the frequency of M (for monthly) and my date range is today and a year in the future, then I will return twelve occurrences of that task from my output.
You'd think this is simply, but I've spent the last few days bleeding from my eyes trying to figure this one out. The output needs to also say when the task is next due.
How about something like this. You can expand the case to allow for other frequencies
DECLARE #Table TABLE(
TaskName VARCHAR(10),
StartDate DATETIME,
Frequency VARCHAR(10) --let say D,W,M daily, weekly, monthly
)
INSERT INTO #Table (TaskName,StartDate,Frequency) SELECT 'TADA', '15 Jan 2009', 'M'
DECLARE #StartDate DATETIME,
#EndDate DATETIME
SELECT #StartDate = '27 Nov 2009',
#EndDate = '27 Nov 2010'
;WITH cte AS(
SELECT TaskName,
StartDate,
Frequency
FROM #Table
UNION ALL
SELECT TaskName,
CASE
WHEN Frequency = 'M' THEN DATEADD(mm,1,StartDate)
END,
Frequency
FROM cte
WHERE StartDate <= #EndDate
)
SELECT *
FROM cte
WHERE StartDate BETWEEN #StartDate AND #EndDate
OPTION (MAXRECURSION 0)
Related
I have a table within Visual Studio and I am wanting to create an input field in for a StartDate and another input field for an EndDate where a user selects a date for both and it will return all records that have a date that falls between the Start and End dates that the user chooses. I would also like the user to have the option to only search for the StartDate and leave the EndDate null so essentially only having 2 input fields for the table (or 1 if End Date is null).
I have this right now which returns the date the user selects but only on that date:
(Date = #Date) AND (#Date BETWEEN #StartDate AND #EndDate)
#StartDate is a date that comes before any date in the DB. #EndDate is the current day. This is just in case a user types in a date that is not within the date range of the database and it will return an error.
I have tried making the parameter #StartDate equal to #Date so when the user selects a date, it will make that the starting date. I also have the input field for the user to select an EndDate which seems to work. I just can't get the start date parameter to work like I want.
These are the queries I have tried:
1.
(Date = #Date) AND (#StartDate = #Date) AND (#Date BETWEEN #StartDate AND #EndDate)
2.
(Date = #Date) AND (#Date BETWEEN #Date AND #EndDate)
How do I modify this query/parameters to get the user to select a start date and an end date in input fields and for the table to return all the records that are between those dates?
(Date = #Date) AND ...
This will always require Date to equal #Date to be true, regardless of the rest unless some OR ... comes along.
Assuming the two fields fill #StartDate and #EndDate (to me it isn't clear, why there is a third variable, #Date) you're probably searching for something like:
#EndDate IS NULL
AND Date = #StartDate
OR Date BETWEEN #StartDate
AND #EndDate
If #EndDate IS NULL (the user hasn't put anything in the respective field) Date = #StartDate has to be true. Otherwise Date BETWEEN #StartDate AND #EndDate (which won't ever be true if #EndDate IS NULL just in case you wonder).
I want to get all sunday date between two dates and get last day between two date, how can i do that in mysql?
Example :
start date | end date
2017-03-01 | 2017-03-31
then the results are :
2017-03-05
2017-03-12
2017-03-19
2017-03-26
2017-03-31
Start date and end date possible to change, please advise me.
Thank you
Since you now mentioned that you don't have a table for the dates, you could approach it like this if you don't want to add a generic calendar table on your database.
declare #startdate datetime
declare #enddate datetime
DECLARE #startdateLoop datetime
select #startdate = CAST(start as DATE), #enddate = CAST(end_date as DATE) from #t
set #startdateLoop = #startdate
CREATE TABLE #tempCal
(dates datetime)
WHILE #startdateLoop != #enddate
BEGIN
INSERT INTO #tempCal
SELECT #startdateLoop
SET #startdateLoop = DATEADD(dd, 1, #startdateLoop)
END
SELECT * FROM #tempCal
WHERE dates between #startdate and #enddate and DAYOFWEEK(dates) = 1
You may turn this into a procedure if you want to.
Would still be nice if you DO HAVE a calendar table; as Tim has suggested.
MySQL has a DAYOFWEEK() function which would return 1 for any date which is a Sunday:
SELECT date_column
FROM yourTable
WHERE (date_column BETWEEN '2017-03-01' AND '2017-03-31' AND
DAYOFWEEK(date_column) = 1) OR -- any Sunday
date_column = '2017-03-31' -- or the last date in the range
I am assuming that yourTable already has dates in it. If you need help with populating a table with a range of dates, this problem has been covered well before on Stack Overflow, q.v. here:
How to populate a table with a range of dates?
Demo here:
Rextester
SELECT calender FROM calender WHERE calender.calender >='2017-03-01' AND calender.calender <='2017-03-31' AND DAYOFWEEK(calender) = 1 OR calender = '2017-03-31' Group By calender
This is #Tim Answer
Thanks Tim
For sql server 2008: what is the best way to filter results, to return only results that are in the same month as a certain date?
The best I could come up with is the following:
-- set up test data
DECLARE #TABLE1 AS TABLE (
ID INT,
STRING VARCHAR(MAX),
DATECOLUMN DATETIME
)
INSERT INTO #TABLE1
SELECT
0 ID,
'TABLE1 0' STRING,
CONVERT(DATETIME, '2016-10-13 12:45:00', 102) DATECOLUMN
UNION ALL SELECT 1, 'TABLE1 1', CONVERT(DATETIME, '2016-9-13 12:45:00', 102)
UNION ALL SELECT 2, 'TABLE1 2', CONVERT(DATETIME, '2016-10-1 00:00:00', 102)
UNION ALL SELECT 3, 'TABLE1 3', CONVERT(DATETIME, '2016-10-31 23:59:59', 102)
-- set up constraint
DECLARE #SOMEDATE DATETIME = CONVERT(DATETIME, '2016-10-13 12:45:00', 102)
-- filter
SELECT * FROM #TABLE1
WHERE MONTH(DATECOLUMN) = MONTH(#SOMEDATE)
Is this the best way?
Your query will return records where the month of DateColumn matches the month of #SomeDate, although (as #Jayvee points out) this would be true regardless of the year. So if that's what you want, your solution is fine.
But you asked whether that was the best solution. I would say no, because this won't take advantage of any index you may have that includes DateColumn.
So this is what I would do, if I were on SQL Server 2008:
declare #someDate datetime = GetDate()
declare #startDate date
declare #endDate date
-- I want the first day of the month, at 12:00:00AM (no time component).
-- The DateAdd expression subtracts days, and converting to the Date data type
-- ensures that I don't have a time component hanging around.
set #startDate = convert(date, DateAdd(day,- DatePart(day, #someDate) + 1, #someDate))
-- I want the first day of the next month. This is easy:
set #endDate = DateAdd(month, 1, #startDate)
-- Here's my actual query, that can take advantage of indexes that include DateColumn:
select *
from Table1
where DateColumn >= #startDate and DateColumn < #endDate
Note that I said >= for start date but < for the end date. That ensures that I'll pick up any date entries for the last day of the month that have a non-zero time component, but won't go into the next month.
The best way for a long-term solution is to create a date dimension table (you can find scripts out there to auto-generate one). The date dim table will just contain a list of dates as far back and forward as you care to go, and it includes columns like DayOfWeek, QuarterOfYear, YYYYMM, etc., so you can join CAST(YOURDATE AS DATE) to the date dim's date and pull nifty date info. Here you can join both of your tables to the date dim and use WHERE t1.YYYYMM = t2.YYYYMM.
Could someone advise how I can go about counting the number of first day of month between two dates?
For example: 02/01/2015 to 05/05/2015 will count as 4.
It can be accomplished easily like this:
DECLARE #sd DATE = '02/02/2015', #ed DATE = '05/01/2015'
SELECT DATEDIFF(mm, #sd, #ed) + CASE WHEN DAY(#sd) = 1 THEN 1 ELSE 0 END
If you have a sequence of dates stored somewhere (like in a calendar table) you can easily count the dates matching the day(date) predicate. If you don't have any suitable table with a date sequence you can use a recursive common table expression to generate one on the fly like this:
declare #start date
set #start = '02/01/2015'
declare #end date
set #end = '05/05/2015'
;with dates (date) as (
select #start date
union all
select dateadd(day, 1, date) as date from dates where date < #end
)
select count(*) no_of_firsts from dates where day(date) = 1
Sample SQL Fiddle
Am using Sql Server 2008, I have a column named Date in my table, and I want to get the datas for the particular date.... I need to give this Date in my WHERE condition.
for example, if I want to get the records for the particular month in the given date, how can I use this Date in WHERE condition.
DATANAME(MONTH,'#Date')
if I give like this in my query I can get the month from the given DATE, the same way I tried by putting in WHERE condition like,
WHERE DATE= DATANAME(MONTH,'#Date')
here it reports conversion error...how can I display the datas for a particular month, can anyone help me
If you want a month of data for a table you should check against an interval. The query is not able to use indexes on the date column if you are applying functions on the column.
Use something like this to get data for April 2012.
-- The date parameter
declare #Date datetime
set #Date = '2012-04-11'
declare #FromDate datetime
declare #ToDate datetime
-- set FromFate to first of april
set #FromDate = dateadd(month, datediff(month, 0, #Date), 0)
-- set ToDate to first of may
set #ToDate = dateadd(month, 1+datediff(month, 0, #Date), 0)
select *
from YourTable
where [Date] >= #FromDate and [Date] < #ToDate
If you want to show data for a particular year and month you can use the YEAR and MONTH functions:
SELECT ...
FROM ...
WHERE YEAR(mydate) = 2012 AND MONTH(mydate) = 3 -- March, 2012
To me it seems that your field Date is not of type varchar or nvarchar, so using a condition where a Datetime = string is obviously wrong.
Have you tried
WHERE DATE= #Date
Shouldn't it be:
DATENAME(MONTH, #Date)
Instead of:
DATANAME(MONTH,'#Date')
(Notice "DATA" vs "DATE" and #Date isn't in quotations)
Then to use this against a date/datetime column you would have to cast both sides like below:
WHERE datename(Month, [Date]) = datename(Month, [Date])
Warning: The above does not use any indexes so isn't as efficient as "WHERE Date = Date"
First: Remove '' from variable. #Date, not '#Date'
If you want to find dates from specific month. (You have to remember about year condition also)
WHERE DATANAME(MONTH, #Date) = 'April'
if you want to find exact date:
WHERE DATE = #date