SQL find out how many days into year date is - sql

I want to work out an annual figure as a proportion of the year based on the date - so if 400 is the annual figure, I want to divide this by 365 then multiply the result by however many days is equivalent to today's date (e.g. (400/365)*160)).
Is there a way of doing this with a SQL server select statement to avoid manually entering the 160 figure?
The 400 figure is coming from a standard field named HES.
Thanks.

You can use datepart(dayofyear, getdate()) - will return a number representing today's day of the year. See MSDN DatePart

Since this is sql server and the other answer is using mysql I will post the sql server version.
select DATEPART(dayofyear, getdate())

For your calculation, you might want to take leap years into account. SQL Server has a convenient datepart(dayofyear, . . ) functionality. The complete solution would look like:
select datepart(dayofyear, dateadd(day, -1, cast(cast(year(getdate() + 1) as varchar(255)) + '0101' as date))) as daysinyear,
datepart(dayofyear, getdate()) as currentday,
datepart(dayofyear, getdate()) * 1.0 / datepart(dayofyear, dateadd(day, -1, cast(cast(year(getdate() + 1) as varchar(255)) + '0101' as date)))as daysinyear
Note that SQL Server does integer division, so to get a fraction, you need to convert to a decimal representation of some sort (* 1.0 is just a simple way of doing this).

Related

New to SQL Server looking for assistance for a datetime conversion

this is my first submission on Stack Overflow, and I am open to any suggestions on structuring my questions.
I am new to SQL Server, and I have a line of code I that I don't understand.
Can someone please explain this?
declare #prior_year datetime = convert(date, '12/31/' + convert(varchar, datepart(yy, #start_date) - 1))
This is a problematic way to determine the last day of the year before the date(time) stored in some variable.
convert(date, '12/31/' + convert(varchar, datepart(yy, #start_date) - 1))
In English, working outward:
datepart(yy, #start_date)
Tell me the year of the variable #start_date. This is poor form because, if we mean year, we should spell out YEAR (see "Date Parts" in this post). I said this already once today, but this is just laziness, it's like "I'm going to type just enough characters to avoid an unexpected result, but not enough characters to make my intent clear." Worse is YYYY, which I see often - you have a choice between YYYY and YEAR, why not type the one that's actually a word?
datepart(yy, #start_date) - 1
--------------------------- ^^^
Subtract one from that year.I don't have any issues here, but it may be clearer to use an explicit DATEADD() against the variable first, and then extracting the year from that, since things like <some date thing> - 1 can be misread as an attempt to subtract a day (also covered in the shorthand post referenced above).
convert(varchar, datepart(yy, #start_date) - 1))
--^^^^^^^^^^^^^^^^
Convert that explicitly to a string.
Also poor form here because we should always specify the length of variable-width data. In some cases this can lead to unexpected truncation. See this post.
'12/31/' + convert(varchar, datepart(yy, #start_date) - 1))
--^^^^^^^^^^
Prefix that year with 12/31 to produce a mm/dd/yyyy string.
More poor form, because this then assumes the user has US English regional settings, MDY dateformat, etc. If you're going to insist on building a string that represents a date, always use a standard, unambiguous format: YYYYMMDD. (And FWIW YYYY-MM-DD is ambiguous, try it with SET LANGUAGE FRENCH;). See this post.
convert(date, <the rest>)
Converts the whole expression to a date.
A better solution
Ideally we should not be using strings anywhere along the line for any of this. We have built-in functions that provide all kinds of native date handling capabilities without having to worry about languages, regional settings, date format preferences, or string lengths:
SELECT DATEFROMPARTS(YEAR(#start_date) - 1, 12, 31);
-- or, more explicitly:
SELECT DATEFROMPARTS(DATEPART(YEAR, #start_date) - 1, 12, 31);
The other way you can think about this is that the last day of last year is the same day as the day before the first day of this year. Thinking about it in these terms can make it much easier to conceptualize when you are doing things like prior month, where determining the last day of the previous month is more tedious. Or if you are finding endpoints for range queries, because the end of the current reporting period is never as deterministic as the start of the next reporting period. More on that here.
SELECT DATEADD(DAY, -1, DATEFROMPARTS(YEAR(#start_date), 1, 1));
Also of potential use:
Dating Responsibly
Simplify Date Period Calculations in SQL Server
SQL Server DateTime Best Practices
Four short videos in this series
Reading this from the inside out:
We're first finding the year of the date using DATEPART and then subtracting 1 so for a value for today's date: 2020-08-18 we'd be getting an integer value of 19
datepart(yy, '2020-08-18') - 1)
We're then using convert on that value to change it to a varchar:
convert(varchar, 19)
We're then using that new varchar to create a string:
'12/31/' + '19'
Finally we're using convert again to create a date from the string
convert(date, '12/31/19')
Tony,
For completeness please provide the definition and assignment for #start_date. Assuming the statement you provided works, it is probably defined something like
declare #start_date date
set #start_date = '07-01-2020'
Working from the inside out, we can then break the statement down like so ...
This will extract the year value
datepart(yy, #start_date)
This will subtract 1 from the #start_date year value, assuming 2020, this returns 2019
convert(varchar, datepart(yy, #start_date) - 1)
And then this will convert that to the last day of the previous year.
convert(date, '12/31/' + convert(varchar, datepart(yy, #start_date) - 1))
So the statement simply sets the new field to the last day of the prior year.
declare #prior_year datetime = convert(date, '12/31/' + convert(varchar, datepart(yy, #start_date) - 1))
This SQL code declares a #prior_year datetime variable that is hard coded to 12/31/. datepart is used to extract the previous year from another datetime variable #start_date` that is passed in and tacks the returned value onto the end of the '12/31/' hard coded string. So; its really just a formula of 12/31/(#start_date prior year)
So if #start_date is 8/20/2020
You will end up with the output of 12/31/2019
declare #start_date datetime = getdate()
declare #prior_year datetime = convert(date, '12/31/' + convert(varchar, datepart(yy, #start_date) - 1))
select #prior_year
Result:

Sql Server Select Only Date Part From DateTime

I have problem in Sql Server for select only date part from DateTime.
The value of DateTime is 2014-05-01 00:00:00.000.
If tried this query I don't have error and the output is correct:
SELECT CONVERT(VARCHAR(10),'2014-05-01 00:00:00.000',110)
2014-05-01
If tried this other query in the doTable:
SELECT
TOP 100 *
FROM
[n].[a2].[DOTABLE]
WHERE
CONVERT(VARCHAR(10),data,110) > DATEADD(DAY, - 1, getdate())
ORDER BY
data DESC;
I have this error:
SQL Server Error Messages - Msg 242 -
The conversion of a char data type to a datetime data type
resulted in an out-of-range datetime value.
The version of SQL server is:
Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86)
Oct 14 2005 00:33:37
Copyright (c) 1988-2005 Microsoft Corporation
Standard Edition on Windows NT 6.1 (Build 7600: )
I suppose I'm not doing right but I know why.
I think the following is a better way to do what you want:
where date >= dateadd(day, 0, datediff(day, 0, getdate()) - 1)
This truncates the current date to midnight yesterday, which I am guessing is what you really want.
For your method, try using format 120:
SELECT TOP 100 *
FROM [n].[a2].[DOTABLE]
WHERE CONVERT(VARCHAR(10), data, 120) > DATEADD(DAY, - 1, getdate())
ORDER BY data DESC;
You can do this on both sides:
SELECT TOP 100 *
FROM [n].[a2].[DOTABLE]
WHERE CONVERT(VARCHAR(10), data, 120) > CONVERT(varchar(10), DATEADD(DAY, - 1, getdate()), 120)
ORDER BY data DESC;
This format is YYYY-MM-DD which is useful for comparisons.
Then, upgrade SQL Server, and use the date data type instead.
Verified your query in SQL server 2008. It's running fine may be a specific issue related to SQL server 2005 for conversion between varchar and date time.
You can add explicit conversion to date type here
SELECT
TOP 100 *
FROM
[n].[a2].[DOTABLE]
WHERE
CAST( CONVERT(VARCHAR(10),data,110) as datetime) > DATEADD(DAY, - 1, getdate())
ORDER BY
data DESC;
My suggestion is to use the following conversion to zero out the date part you don't requre (in this case time):
declare #n int = datediff(day, 0, [some_datetime_col]);
The above part will return the number of days since SQL Server's epoch time, as an integer. Then, to finish off the conversion:
select dateadd(day, #n, 0);
This adds back that number of days, returning a datetime with no time portion. To apply it to your example:
where
datediff(day, 0, data) > (datediff(day, 0, getdate()) - 1)
In your case, you don't need to do the conversion back to datetime as it's just a where clause; you can compare integers pretty efficiently and get the same result.
The added benefit of this method is that you can just as easily apply it to months (get first day of month, for example) and years. More care needs to be taken with weeks, but that's beyond the scope of this answer.
why you convert date to varchar?
try this query
SELECT TOP 100 *
FROM [n].[a2].[DOTABLE]
WHERE data > DATEADD(DAY, - 1, getdate())
ORDER BY data DESC;

sql compare datetime today

I hope anyone can translate my abstract query.
I want to select * from TABLE where ( [MYDATETIMEROW] < (TODAY - 3 Days)).
Does I have to Convert, cast or use datepart or anything else?.. im confused.
Are there simple rules? I would'nt have problems to do that with linq but simple sql I learned just hardly.
Thank you and best regards.
In simple terms:
Select * from Table where MyDateTimeRow < dateadd(dd,-3,getdate())
But using getdate() will provide both a date and a time, experience says that this is unlikely to be exactly what you want - you might want to strip the time down and just consider the date portion
Select * From Table where MyDateTimeRow < dateadd(dd, datediff(dd, 0, getdate()) - 3, 0)
You want the DateAdd function to manipulate dates and the GetDate function to get the current date:
SELECT * FROM MyTable WHERE [MyDateTimeRow] < DateAdd(dd, -3, GetDate())

How can I get the date of the first second of the year with SQL?

I'm working on a purging procedure on SQL Server 2005 which has to delete all rows in a table older than 1 year ago + time passed in the current year.
Ex: If I execute the procedure today 6-10-2009 it has to delete rows older than 2008-01-01 00:00 (that is 2007 included and backwards).
How can I get the date of the first second of the year?
I've tried this:
select cast((DATEPART(year, getdate()) -1 )AS DATETIME);
but I get 1905-07-02 00:00:00.000 and not 2008-01-01 00:00 (as I wrongly expected).
Can someone help me, please?
EDIT: This was returning current year, when the question was for previous year. Code has been corrected to reflect this.
use this
select DATEADD(yy, DATEADD(yy, DATEDIFF(yy,0,getdate()), 0), -1)
OR to use your variable:
select DATEADD(yy, DATEADD(yy, DATEDIFF(yy,0,#YourDateTimeValue), 0), -1)
This will work:
select cast('01 jan' + CAST((DATEPART(year, getdate())-1) as varchar) AS DATETIME);
(I know it's not the "best" solution and probably involves more casts than necessary, but it works, and for how this will be used it seems to be a pragmatic solution!)
SELECT DATEADD(year, DATEDIFF(year, 365, GETDATE()), 0)

SQL Server: Get data for only the past year

I am writing a query in which I have to get the data for only the last year. What is the best way to do this?
SELECT ... FROM ... WHERE date > '8/27/2007 12:00:00 AM'
The following adds -1 years to the current date:
SELECT ... From ... WHERE date > DATEADD(year,-1,GETDATE())
I found this page while looking for a solution that would help me select results from a prior calendar year. Most of the results shown above seems return items from the past 365 days, which didn't work for me.
At the same time, it did give me enough direction to solve my needs in the following code - which I'm posting here for any others who have the same need as mine and who may come across this page in searching for a solution.
SELECT .... FROM .... WHERE year(*your date column*) = year(DATEADD(year,-1,getdate()))
Thanks to those above whose solutions helped me arrive at what I needed.
Well, I think something is missing here. User wants to get data from the last year and not from the last 365 days. There is a huge diference. In my opinion, data from the last year is every data from 2007 (if I am in 2008 now). So the right answer would be:
SELECT ... FROM ... WHERE YEAR(DATE) = YEAR(GETDATE()) - 1
Then if you want to restrict this query, you can add some other filter, but always searching in the last year.
SELECT ... FROM ... WHERE YEAR(DATE) = YEAR(GETDATE()) - 1 AND DATE > '05/05/2007'
The most readable, IMO:
SELECT * FROM TABLE WHERE Date >
DATEADD(yy, -1, CONVERT(datetime, CONVERT(varchar, GETDATE(), 101)))
Which:
Gets now's datetime GETDATE() = #8/27/2008 10:23am#
Converts to a string with format 101 CONVERT(varchar, #8/27/2008 10:23am#, 101) = '8/27/2007'
Converts to a datetime CONVERT(datetime, '8/27/2007') = #8/27/2008 12:00AM#
Subtracts 1 year DATEADD(yy, -1, #8/27/2008 12:00AM#) = #8/27/2007 12:00AM#
There's variants with DATEDIFF and DATEADD to get you midnight of today, but they tend to be rather obtuse (though slightly better on performance - not that you'd notice compared to the reads required to fetch the data).
Look up dateadd in BOL
dateadd(yy,-1,getdate())
GETDATE() returns current date and time.
If last year starts in midnight of current day last year (like in original example) you should use something like:
DECLARE #start datetime
SET #start = dbo.getdatewithouttime(DATEADD(year, -1, GETDATE())) -- cut time (hours, minutes, ect.) -- getdatewithouttime() function doesn't exist in MS SQL -- you have to write one
SELECT column1, column2, ..., columnN FROM table WHERE date >= #start
I, like #D.E. White, came here for similar but different reasons than the original question. The original question asks for the last 365 days. #samjudson's answer provides that. #D.E. White's answer returns results for the prior calendar year.
My query is a bit different in that it works for the prior year up to and including the current date:
SELECT .... FROM .... WHERE year(date) > year(DATEADD(year, -2, GETDATE()))
For example, on Feb 17, 2017 this query returns results from 1/1/2016 to 2/17/2017
For some reason none of the results above worked for me.
This selects the last 365 days.
SELECT ... From ... WHERE date BETWEEN CURDATE() - INTERVAL 1 YEAR AND CURDATE()
The other suggestions are good if you have "SQL only".
However I suggest, that - if possible - you calculate the date in your program and insert it as string in the SQL query.
At least for for big tables (i.e. several million rows, maybe combined with joins) that will give you a considerable speed improvement as the optimizer can work with that much better.
argument for DATEADD function :
DATEADD (*datepart* , *number* , *date* )
datepart can be: yy, qq, mm, dy, dd, wk, dw, hh, mi, ss, ms
number is an expression that can be resolved to an int that is added to a datepart of date
date is an expression that can be resolved to a time, date, smalldatetime, datetime, datetime2, or datetimeoffset value.
declare #iMonth int
declare #sYear varchar(4)
declare #sMonth varchar(2)
set #iMonth = 0
while #iMonth > -12
begin
set #sYear = year(DATEADD(month,#iMonth,GETDATE()))
set #sMonth = right('0'+cast(month(DATEADD(month,#iMonth,GETDATE())) as varchar(2)),2)
select #sYear + #sMonth
set #iMonth = #iMonth - 1
end
I had a similar problem but the previous coder only provided the date in mm-yyyy format. My solution is simple but might prove helpful to some (I also wanted to be sure beginning and ending spaces were eliminated):
SELECT ... FROM ....WHERE
CONVERT(datetime,REPLACE(LEFT(LTRIM([MoYr]),2),'-
','')+'/01/'+RIGHT(RTRIM([MoYr]),4)) >= DATEADD(year,-1,GETDATE())
Here's my version.
YEAR(NOW())- 1
Example:
YEAR(c.contractDate) = YEAR(NOW())- 1
For me this worked well
SELECT DATE_ADD(Now(),INTERVAL -2 YEAR);
If you are trying to calculate "rolling" days, you can simplify it by using:
Select ... FROM ... WHERE [DATE] > (GETDATE()-[# of Days])