I am having some issues with getting dates showing up in my query when I changed the dates in my variable, below is what I have declared.
declare #record int;
declare #start_date date;
declare #end_date date;
set #record = 2;
set #start_date = '2016-03-01';
set #end_date = '2016-03-31';
What I have created is temp tables which populate my data by Date ranges. The dates are set up as below
- Daily 2016-01-15
- weekly 2016-51
- Monthly 2016-04
- Quarterly 2016-01
- Yearly 2016
So when I declare the dates above and filter by yearly I should get data back, in fact no matter what date I put in for yearly I should get results but nothing is showing up.
When I declare the start date = 2016-01-01 it returns data for everything I filter by.
Can anybody offer some advice on a way to fix this problem I have no idea.
I don't know what is your query which is not working, but the basic isead sould be like that:
select * from YourTempTable where datepart (yy, DateField) = datepart(yy, #start_date)
of course this is not optimal for big tables as it wouldn't use any index.
Better would be to construct a #DateFrom and #DateTo variables based on the period you are looking for and the reference dates described above and make your select accordingly:
select * from YourTempTable where DateField between = #DateFrom and #DateTo
Related
I have a table which has list of some events with dates. I am trying to write a stored procedure that will return only the upcoming events.
I have written the following query in the stored procedure:
SELECT *
FROM Events
WHERE tDate >= (select CAST(GETDATE() as DATE))
But this is not returning correct result. This is also showing results that have dates less than current date. How to write a query that will return all the events that have date equal or greater than today's date.
Edit: Dates that have been entered on the table have the format yyyy/dd/mm and getdate() returns date in the format yyyy/mm/dd. I think this is causing the problem. Dates that have been entered into the table has been taken using jquery date picker. Any solution to this problem?
Not sure why you have an additional select
SELECT *
FROM Events
WHERE tDate >= CAST(GETDATE() as DATE)
your DATE data is incorrectly stored within Sql Server. When your application passes the string '2015-09-04' and you save that your date column, it is saved as 4th Sept 2015 and not 9th April 2015. Hence your query returns such rows as they are greater than GETDATE().
Example
DECLARE #D VARCHAR(10) = '2015-09-04'
SELECT CONVERT(VARCHAR(20),CONVERT(DATE,#D),109)
you need to fix your data and then use a CONVERT with style when saving dates in your table from application, using something like this. CONVERT(DATE, '20150409',112)
DECLARE #D VARCHAR(10) = '20150409'
SELECT CONVERT(VARCHAR(20),CONVERT(DATE,#D,112),109)
Refer these threads for more info:
Impossible to store certain datetime formats in SQL Server
Cast and Convert
I'm trying to retrieve records by comparing date values as follows :
declare #fromdate as date
declare #todate as date
set #fromdate='2013-04-01'
set #todate='2013-04-13'
select createdon,
convert(varchar,PhoneCall.createdon,101) as createdon,
convert(varchar,#fromdate,101) as fromdate
from
PhoneCall
where convert(varchar,PhoneCall.createdon,101) >= convert(varchar,#fromdate,101) and convert(varchar,PhoneCall.createdon,101) <= convert(varchar,#todate,101)
There is something wrong in the comparison, I've tried using various conversion formats but I'm not receiving correct results.
The query above has been my latest trial, although it looks correct, it doesn't take into account the comparison of the Year. So the results displayed are as follows:
Createdon ConvertedCreatedOn ConvertedFromDate
2013-05-08 14:13:16.000 05/08/2013 05/01/2013
2014-05-01 17:10:03.000 05/01/2014 05/01/2013
EDIT:
This is a query I'll use for a report. The #fromdate and #todate are report parameters that will be entered manually by the user, so I have to make sure that they're in the same format with the database date format.
Why do you convert all DATE fields/params to VARCHAR? Just use DATE comparison:
where PhoneCall.createdon BETWEEN #fromdate AND #todate
IF you NEED to use varchar then you should use 102 format (yyyy.mm.dd) instead of 101 (mm/dd/yyyy). In this case it can be used to compare dates as strings.
Typically I need to remove time info from GETDATE(). I need this because I have some DateTime fields where I know I am storing only date information so to make reliable comparisons (MyDate < GETDATE()) I need to remove time information from GETDATE()). Of course I could use the DATE datatype in MyDate, but this is ok for new applications, not for legacy ones.
I used to do it with CAST, but since in SQL Server 2008 there is also the DATE datatype it seems more readable.
Old approach
DECLARE #Today DateTime
SET #Today = (CAST(FLOOR(CAST( GETDATE() AS FLOAT)) AS DATETIME))
select #Today
New approach
DECLARE #TodayDate Date
Set #TodayDate = GETDATE()
select #TodayDate
May I go with the second or is there any caveat? (of coruse I use 2008 only!)
No caveats. Indeed it is the best way according to this answer.
TSQL Function to calculate 30 WORKING days Date from a Specified Date (SQL Server 2005)?
Input parameters would be Date and Number of Working Days.
Output would be the Calculated Date.
This would exclude Saturday, Sunday, Holidays and Day Holiday was observered.
i.e. If the Holiday falls on a weekend but it is observed on the Friday or Monday after the holiday.
For the Holidays we have a table with holiday and day it is being observed date.
Have a look at this article by Celko - in general you need to "pre-calculate" a calendar table to take in account all possible vagaries like Easter, bank holidays etc.
There's one right in the SQL online help if you scroll down to UDF to return the number of business days, including a check to a bank holidays table
you can tweak this.
Instead of writing a tsql function, it might easier if you build a table that's similar to the Date Dimension (DimDate) table in data warehouse. DimDate would contain a column named isHoliday. You can also add other columns that might be useful. Then you write a script to populate DimDate
Then you can run a query off it.
I don't have a table of holidays handy, so I haven't tested this very much - but as nobody else has attempted an answer, here's how I'd start:
declare #tempDate datetime,
#StartDate datetime,
#WorkingDays int,
#NonWorkingDays int,
#TargetDate datetime
set #StartDate = '2010-10-26' --Change this to a paramter
set #WorkingDays = 9 --Change this to a parameter
set #NonWorkingDays = -1
/*Work out the answer ignoring holidays */
set #tempDate = dateadd(d,#WorkingDays,#StartDate)
while (dateadd(d,#WorkingDays + #NonWorkingDays, #StartDate) < #tempDate)
begin
/*Work out how many holidays are in the interval we've worked out*/
select #NonWorkingDays = count(HolidayDate)
from Holidays
where HolidayDate between #StartDate and #tempDate;
/*Extend the interval to include the holidays we've just found*/
set #tempDate = dateadd(d,#NonWorkingDays,#tempDate)
/*See if #NonWorkingDays has changed with the new #tempDate*/
select #NonWorkingDays = count(HolidayDate)
from Holidays
where HolidayDate between #StartDate and #tempDate;
end
set #TargetDate = dateadd(d,#WorkingDays + #NonWorkingDays, #StartDate)
print 'Target Date: ' + cast(#TargetDate as varchar(50))
Note this only works for Holidays at the moment - not weekends. You'd have to load all weekends into the holiday table (or join to a weekends table or use the DATENAME function) but the calculation should be the same.
Not sure how your Holiday table handles duplicate dates (eg. Boxing Day and St Stephen's Day both fall on 26th Dec) so you might need to take account of that.
I have a datetime field in my table. I want to delete records based on a date but I am not interested in the time element. How would I write the SQL for this ? I am using MS SQL 2008.
For best use of indexes, I'd go for this kind of approach:
To delete all records for 1st December:
DECLARE #DateToDelete DATETIME
SET #DateToDelete = '20091201'
DELETE FROM MyTable
WHERE MyDateField >= #DateToDelete AND MyDateField < DATEADD(dd, 1, #DateToDelete)
The alternatives include:
DELETE FROM MyTable
WHERE CAST(CONVERT(VARCHAR(10), MyDateField, 120) AS DATETIME) = #DateToDelete
which converts each datetime value to just it's date part.
But I'd still go with my original way as it allows for more efficient execution.
If you use MS SQL 2008 then you could convert to a new DATE type
DELETE FROM table WHERE date_filed >= CONVERT(DATE,GETDATE())
Is the time relevant in any other place? If not, then you should use a DATE column instead. If you cannot, then the best way to seek a date part of a datetime in a WHERE clause is to use a range:
... WHERE dateColumn BETWEEN '20091221' and '20091222';
Note that given the datetime accuracy of 3ms a datetime like 20091221 23:59:59.999 may be aproximated to 20091222 00:00:00.000 and this can sometime create problems.
There is a great collection of blog posts on the topic of datetime at T-SQL Tuesday #001 (Date/Time Tricks): The Roundup
Try this:-
declare #date datetime
set #date = '2006-11-09'
select #date, dateadd(ms, -1, DATEADD(dd,1,#date))
delete from login
where datecreated between #date AND dateadd(ms, -1, DATEADD(dd,1,#date))
This is what datediff is for:
delete from Table where datediff(day,'2009-12-09',date_filled) = 0