Get query results for all date values besides current month - sql

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)))

Related

How to get the records of last month in SQL Server?

I want to get the records of last month based on my table [Sales], variable "SoldDate" in SQL Server.
For example, if today is 29/09/2021, I want to get the data for 01/08/2021-31/08/2021
The "SoldDate" variable is in the format 2018-04-11 00:00:00.000.
I would really appreciate your help! I have no idea how to get this to work :(
You can use eomonth() :
SELECT DATEADD(DAY, 1, EOMONTH(SoldDate, -2)) AS StartDate, EOMONTH(SoldDate, -1) AS EndDate
The best way to search through an indexed table is to calculate what date range you need, and filter on that. You can use DATEADD and EOMONTH for this. Note that since you have a time component, you cannot just use EOMONTH
SELECT *
FROM YourTable
WHERE SoldDate >= DATEADD(day, 1, EOMONTH(GETDATE(), -2))
AND SoldDate < DATEADD(day, 1, EOMONTH(GETDATE(), -1))
EOMONTH gives you the end of a month, the second parameter denotes how many months to shift.
Note correct use of the half-open interval >= AND <, this dealls correctly with the time component.

Selecting Dynamic date in a date range of sql

This is what my query's date range is:
WHERE
date BETWEEN 20190101 AND [here date should come as last year YTD -1]
For example if we use this query today (20201106) (format:yyyymmdd), then the 2nd date should be 20191105.
For more clarity: when I run this query today (20201106) my query should fetch results from date range:
WHERE
date BETWEEN 20190101 AND 20191105
When I run this query tomorrow (20201107), my query should fetch results from the date range:
WHERE
date BETWEEN 20190101 AND 20191106
How can I do this?
Can anyone help?
you can use dateadd() with getdate()
DATEADD(year,-1, GETDATE())
or other function that can get current database time but this should work.
also remember to use convert() to modify the date format into what you want.
WHERE
DATEADD(YEAR,-1, GETDATE()) -- One Day Before Today in the Last Year
AND
DATEADD(yy, DATEDIFF(yy, 0, DATEADD(YEAR,-1, GETDATE())), 0) AS StartOfYear -- The Day 1 of the Last Year
I would phrase this as:
where date >= datefromparts(year(getdate()) - 1, 1, 1)
and date < dateadd(year, -1, convert(date, getdate()))
This filters from the start of last year and the 1 year and 1 day ago.
Note that I changed the filtering strategy to use half-open intervals rather than between. This is somehow more flexible, as it would properly handle a time component in in date, if any, and simplifies the offsetting logic.
Note also that getdate() has a time component, that needs to be removed while offsetting to implement your logic.

Searching data for current date in SQL Server

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

SQL date comparision in yyyy/mm/dd

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)

mssql select GETDATE - all day from 00:00 - 23:59

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