Why is the first query taking less time than the second one in SQL Server?
This query takes 4 seconds to complete:
select *
from salesinvmaster
where day(salesdate) = day(getdate()) and
month(salesdate) = month(getdate()) and
year(salesdate) = year(getdate())
This query takes 10 seconds:
select *
from salesinvmaster
where salesdate between '2017-11-01 00:00:00' and '2017-11-01 23:59:59'
The two queries are different, because today is some day in December, not November 1st.
My guess is that you do not have an index on the salesdate column, and that the first query is returning fewer rows -- hence, it looks faster. For the record, I would recommend writing the logic as one of the following:
where convert(date, salesdate) = convert(date, getdate())
where salesdate >= convert(date, getdate()) and
salesdate < dateadd(day, 1, convert(date, getdate()))
Note that SQL Server does use an index for the conversion of a date/time value to a date. This is one of the rare (only?) times when a function does not prevent the use of an index.
As for the second method, it dispenses with the need to include the time component of the values.
Check the Exeuction plan for the query i think We've got implicit conversions on the date! check this
Related
I need to get values for data excluding current month and taking this year into account.
What I currently have is the following
WHERE 1=1
AND CAST(created_at AS DATE) >= '2018-01-01'
AND MONTH(CAST(created_at AS DATE)) != MONTH(GETDATE())
Obviously this will also exclude 2018 current month data as well which I want to prevent.
I've checked different solutions online but failed to apply it.
I would simply do:
where created_at < dateadd(day, 1 - day(getdate()), cast(getdate as date))
This is also sargable -- a mouthful that means that an index can be used for the query.
You can also write this as:
where created_at < datefromparts(year(getdate()), month(getdate()), 1)
This is actually better and clearer.
The correct WHERE clause related on your question will be
WHERE created_at BETWEEN '2018-01-01' AND (DATEADD(dd, -1 ,DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)))
I have a date column like this 7/24/2017 and when I write the below where clause I get results from hour 7/24/2017 1:00:00.000 AM. I need to get this from 7/24/2017 12:00:00.000 AM. How should this where clause me modified. Please check the following code
Date>= DATEADD(day, -1, convert(date, GETDATE())) and
Date< DATEADD(day, +0, convert(date, GETDATE()))
There doesn't appear to be anything wrong with your code. Are you certain your data contains any times before 1am? Are you certain you appreciate how your SQLServer will format those times/represent them to you?
See this SQLFIDDLE: http://sqlfiddle.com/#!6/047cc/11
Optimisations: you don't need to dateadd a value of 0. You can also subtract 1.0 from a date to get the day earlier and it's a bit less wordy than DATEADD. It works because internally dates are represented as floating point numbers of the number of days since a point in time:
[Date] >= convert(date, GETDATE() -1.0) and
[Date] < convert(date, GETDATE())
Not being that great at sql, i've reached my limit.
I have a date in the yyyy/mm/dd format and i need to get all records "from a week ago"
I think i need some conversion stuff to be done cause this
d.date_begin >= DATEADD(day,-7, GETDATE())
is not working :), i'm TERRIBLE at convert and data type..
This will work if you want records from 7 days ago up to and including today's records
CAST(d.date_begin AS DATE) >= CAST(DATEADD(day,-7, GETDATE()) AS DATE)
where DATEDIFF(month,Your_date_column,getdate()) < 3
SQL server 2012 onwards, if date_begin is of datatype date
where d.date_begin >= cast(DATEADD(day,-7, GETDATE()) as date)
This will get anything in the last 7 days, regardless of time
You should store date/time values using native formats. Ok, sometimes we cannot. But you can easily convert your values to the correct format:
where cast(replace(d.date_begin, '/', '') as date) >= DATEADD(day, -7, GETDATE())
I should note that SQL Server is pretty good about conversions, so your initial code should not generate any errors -- unless you have unusual internationalization settings.
Or, actually, a better way to do this is to convert the current value to a string:
where d.date_begin >= format(dateadd(day, -7, getdate()), 'yyyy/MM/dd')
This is better because it is "sargable", meaning that SQL Server can use an index on the column if available.
SELECT * FROM tbl_name
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
Don't manipulate d.date_begin. Making calculation on a column while comparing can give bad performance. You should manipulate getdate() to get the same format as d.date_begin. In this case it works because the format is yyyy/MM/dd - the comparison will give the same result as if both columns were date columns.
WHERE
d.date_begin >= convert(char(10),DATEADD(day,-7, GETDATE()), 111)
Running MS SQL Server 2008
I have this query:
select count(*) from dbo.study
where study_datetime >= (GETDATE() -1)
that comes back with all of yesterdays exams written to my study table. How would I make it come back with everything done 'today' up to the current time I asked for it? For example I would everything for today from 00:00:00.000 - current time
my values in the 'study_datetime' column look like: 2014-05-06 10:40:31.000
I can't seem to figure this one out. I have tried replacing the '-1' with a '0' but I get back 0 results.
thanks
unfortunately there is no trunc() like in oracle, but since you have the 2008 version you can use:
select count(*) from dbo.study
where study_datetime >= cast(getDate() As Date)
If I understand well (values from same day), I think you can use DATEDIFF function, using the day as datepart.
select count(*) from dbo.study
where datediff(dd, study_datetime, GETDATE()) = 0
and study_datetime <= GETDATE() -- if you need a check for the "future" (datetime after GETDATE() )
To get everything that strictly happened today, just use:
select count(*) from dbo.study
where study_datetime >= cast(getDate() As Date)
and study_datetime < cast(DATEADD(day,1,getdate()) as Date)
When you're working with continuous data, it's almost always better to switch to using semi-open intervals, to ensure that data falls into one and exactly one interval. Usually, when you want "all day", you don't want to exclude things that occurred during the final minute of the day (at e.g. 23:59:37.223 or even at 23:59:59.993). So you'd normally write your query to be >= midnight at the start of the day and < midnight at the start of the following day (note the different types of comparisons)
This is usually a far better idea than trying to compute the last moment of today and use <= (or BETWEEN) for your comparisons.
select count(*) from dbo.study
where study_datetime between :2014-05-06 00:00:00 and :2014-05-06 23:59:59.
It might help you
Im having trouble with this query. I want to not select records that have passed the SYSTIME for the current date but display records for future dates even if they have passed the current SYSTIME
SELECT *
FROM TABLE
WHERE DATE>= CONVERT(date, SYSDATETIME())
AND STARTTIME > CONVERT(time, SYSDATETIME())
This is the query. I know why it doesnt work but I can't think of a way to do what I stated above.
SELECT *
FROM TABLE
WHERE
(
(DATE = CONVERT(date, SYSDATETIME()
AND STARTTIME > CONVERT(time, SYSDATETIME()
)
OR Date > sysdatetime()
)
You need an or condition since date time are in different fields you must first resolve today's date and time and then all future dates regardless of time.
This depends a lot on what the original data types are. Let's assume they are date, time, or datetime.
If you want anything in the future, then this works:
where [date] + starttime > sysdatetime()
If you want just future dates then try:
where [date] > cast(sysdatetime() as date)
The latter is how I interpret your question, but I'm not 100% sure that my interpretation is correct.