SQL DATEADD(weekday, 1, date) does not seem to work? - sql-server

Here is my query:
SELECT ID AS 'securityid'
, date
, DATEADD(DW, 1, adate) AS 'lagged_date_v2'
, DATEADD(DAY, 1, adate) AS 'lagged_date_v1'
, aclose AS 'previous_close'
FROM mytable
WHERE adate BETWEEN '20170101 09:00' AND '20170630 18:00' AND
ID = 100056;
Here are the output from the code above:
I compared the results to DATEADDby day and by weekday and it returns the same results.
Column adate is just typical date, we can tell Jan 28, 2017 is Saturday. However, on this row, both lagged_date_v1 and lagged_date_v2 return Jan 28. If I use DATEADD by weekday correctly, I should see Jan 30 instead Jan 28, right?
My sql server version is 2008.

If I use DATEADD by weekday correctly, I should see Jan 30 instead Jan
28, right?
Wrong. In SQL Server, weekday doesn't mean days that aren't weekend days. It means which day of the week (1-7) is the day in question based on the current datefirst setting.

Related

T-SQL select date withing 30 days range

I would like to select all the rows with dates between 30 days range from today,
so between 22-04-2022 till 22-05-2022,
I've tried
SELECT DATEXP, ID FROM TABLE
where DATEXP > cast(getdate() + 30 as date) and DATEXP <= cast(getdate() as date)
but this doesn't seem to do it
You should use the DATEADD() function here:
SELECT DATEXP, ID
FROM yourTable
WHERE DATEXP >= GETDATE() AND DATEXP < DATEADD(day, 30, GETDATE());
Also note that your inequality was incorrect. You should have the earlier date on the left GTE comparison and the later date on the right LT comparison.
Your condition seems to be wrong, you are expecting the date to be >= Today + 30 days BUT less than today.
So if for example.
Today is 22 April 2022
Today + 30 = 22 May 2022
If I have a date DATEXP say 23 May 2022, it can't be >= 22 May 2022 and LESS then 22 April 2022 at the same time.
Maybe you want the Condition to be >= Today AND < Today + 30?

How to get the data in snowflake for past 24 months in snowflake

I have the data for the current month in Snowflake which I am extracting with the below mentioned query
select distinct HPOLICY
, ANNUALPREMIUMAMOUNT
, year(dateadd(year, 0, CURRENT_DATE))
, month(dateadd(month, 0, CURRENT_DATE)) yearmonth
from hub_test
I want to extrapolate this data to the past 24 months which means get the same data with Sep 2019, Aug 2019 and so on till past 24 months.
That query is get all time distinct data, and put a fake current year/month column on it.
If you where doing something like:
select distinct HPOLICY
,ANNUALPREMIUMAMOUNT
,date_part('year', date_column) as year
,date_part('month', date_column) as month
from hub_test
where date_column >= date_trunc('month',CURRENT_DATE());
you would have the current months data, if date_column was the date_of the data in the row.
Therefore to get the last 24 months you would alter that to:
select distinct HPOLICY
,ANNUALPREMIUMAMOUNT
,date_part('year', date_column) as year
,date_part('month', date_column) as month
from hub_test
where date_column >= dateadd('month',-24, date_trunc('month',CURRENT_DATE()));

T-SQL DATEDIFF MONTH January

This may seem like a very simple/silly question but, if I use this code on January, will the output be December (as in January - 1 = December)?
SELECT DATENAME(MONTH, DATEDIFF(MONTH, -1, GETDATE()));
You're using both functions incorrectly. I recommend looking at the online help for more details, but here is an explanation of what you've done...
DATEDIFF()'s last two parameters are both DATETIMEs.
It finds the difference between those two dates.
In years, or months, or days, or hours, etc.
So, when you supply a -1 as the first date it is implicitly CAST to a DATETIME.
As it happens, 0 is 1970-Jan-01 # 00:00:00
Which means that -1 is 1969-Dec-31 # 00:00:00.
You did How many months are there between 1969-Dec-31 and now?
Which is current 1405 months
DATENAME()'s second parameter is also a DATETIME.
It returns the name of the month for that date
Or name of day, etc.
So, when you supplied 1405 as the DATETIME parameter, that also got implicitly converted.
That's 1405 days after 1st Jan 1970
Which is 6th Nov 1973
So DATENAME() returns 'November'
You possibly just want to take one month away from a specific date, and then get its name.
DATENAME( MONTH, DATEADD( MONTH, -1, getDate() ) )
As written, no. As of this current time, it will only return November. This is because you're using DATEDIFF instead of DATEADD.
You can see a bit of why it does this by selecting the DATEDIFF portion:
SELECT DATEDIFF(MONTH, -1, '2017-01-01')
1405
And Select DateName(Month, 1405) returns November.
But, this should be what you meant to use:
SELECT DATENAME(MONTH, DATEADD(MONTH, -1, GETDATE()));
And yes, using that will return December:
SELECT DATENAME(MONTH, DATEADD(MONTH, -1, '2017-01-01'));
December

yearweek on SQL server

How can I extract the year and week combination from a date in SQL Server using T-SQL and have it match the MySQL yearweek result?
For example these MySQL queries (Click here for MySQL SQL Fiddle):
SELECT yearweek('2013-12-31');
SELECT yearweek('2014-01-01');
This returns 201352 for both dates. That is the expected result.
But in SQL Server...
datepart works as expected for the year extract
sometimes datepart does not return the expected value for iso_week
The MySQL result cannot be achieved with this T-SQL query...
SELECT datepart(year, #dt) * 100 + datepart (iso_week, #dt);
T-SQL versions of the MySQL queries above (Click here for T-SQL SQL Fiddle):
SELECT datepart(year, '2013-12-31') * 100 + datepart (iso_week, '2013-12-31');
SELECT datepart(year, '2014-01-01') * 100 + datepart (iso_week, '2014-01-01');
The result is 201352 for the first date and 201401 for the second date.
However, this is not the expected result because...
2014-01-01 belongs to the last week of 2013
So the expected result is 201352
Do any of you more experienced T-SQL developers know how to extract the year/week of a given date and have this match what I see in MySQL?
I need to have the week start on Monday. This is why I am using iso_week. I have tested the results with week anyway and found the same issue. This query also produces 201401 when 201352 is expected.
SELECT datepart(year, '2014-01-01') * 100 + datepart (week, '2014-01-01');
If you look at the ISO_Week datepart definition at http://msdn.microsoft.com/en-us/library/ms174420.aspx, you'll see the following:
ISO 8601 includes the ISO week-date system, a numbering system for
weeks. Each week is associated with the year in which Thursday
occurs...
The numbering system in different countries/regions might not comply
with the ISO standard.
Since January 1, 2014 was a Wednesday; January 2, 2014 was the first Thursday of the year and thus week 1 of 2014 (according to ISO 8601).
Furthermore, looking at the MySQL definitions for yearweek and week, there are several mode options (http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_week)
So, I think you're going to have to write your own yearweek function for the week counting rule you want:
CREATE FUNCTION dbo.yearweek(#date date)
RETURNS INT
as
begin
set #date = dateadd(dd,-datepart(dw,#date)+1, #date)
return datepart(year,#date)*100 + datepart(week,#date)
end
go
select dbo.yearweek('2013-12-31'), dbo.yearweek('2014-01-01')
NOTE: I haven't fully tested this code, and I'm not sure exactly what your requirements are. This is just meant as an example of the type of process you need to follow.
I think it's because you're using "ISO_WEEK" as the datepart
Look at the description under the "ISO_WEEK datepart" here: http://msdn.microsoft.com/en-us/library/ms174420.aspx
using "WEEK" instead might get the desired result
TO extract YEAR, MONTH or DAY you can simply use the YEAR, MONTH and DAY function as shown in the followinf example. for any other part you have to use the DATEPART function , read here for a detailed list of arguements you can pass to DATEPART function.
SELECT YEAR(GETDATE()) AS [YEAR]
, DATEPART(WEEK, GETDATE()) [Week]
UPDATE
SELECT CAST(YEAR(GETDATE()) AS VARCHAR(4)) +'-'
+ CAST(DATEPART(WEEK, GETDATE()) AS VARCHAR(2))
It seems to me that what you want is a week number based on the previous Monday. Is this correct? If so, iso_week is no use to you as it is based on this week's Thursday.
To get the year and week based on the previous Monday, I think you need something like the following.
set datefirst 1 ;
select
SomeDate ,
datename( weekday, SomeDate ) as [WeekdayName] ,
datepart( weekday, SomeDate ) as [Weekday] ,
datepart( week, SomeDate ) as [Week] ,
datepart( iso_week, SomeDate ) as [ISO_week] ,
dateadd( day, -( datepart( weekday, SomeDate ) - 1 ), SomeDate ) as [PreviousMonday] ,
datepart( year, dateadd( day, -( datepart( weekday, SomeDate ) - 1 ), SomeDate ) ) as [MondayYear] ,
datepart( week, dateadd( day, -( datepart( weekday, SomeDate ) - 1 ), SomeDate ) ) as [MondayWeek]
from
dbo.DateDemo
order by
SomeDate ;
Abbreviated sample output is as follows.
SomeDate PreviousMonday MondayYear MondayWeek
2013-12-25 2013-12-23 2013 52
2013-12-26 2013-12-23 2013 52
2013-12-27 2013-12-23 2013 52
2013-12-28 2013-12-23 2013 52
2013-12-29 2013-12-23 2013 52
2013-12-30 2013-12-30 2013 53
2013-12-31 2013-12-30 2013 53
2014-01-01 2013-12-30 2013 53
2014-01-02 2013-12-30 2013 53
2014-01-03 2013-12-30 2013 53
2014-01-04 2013-12-30 2013 53
2014-01-05 2013-12-30 2013 53
2014-01-06 2014-01-06 2014 2

How to select the beginning of the following April in SQL Server?

Could you please help me select a date which is the beginning of a particular following month, e.g. April?
For example, if it is Jan 08 2013, it should select April 01 2013, but if it is June 08 2013, it should select April 01 2014.
Thanks.
I would create a calendar table, then you can simply do something like this:
select
min([Date])
from
dbo.Calendar
where
MonthNumber = 4 and
DayNumber = 1 and
[Date] > getdate()
Querying a calendar table is usually clearer, simpler and more flexible than using date functions. You might also want to consider what happens if today is April 1: do you want today's date, or next year's?
If you're interested in April 1 because it's the start of a financial year, you can add that information to your calendar table directly:
select
min([Date])
from
dbo.Calendar
where
IsStartOfFinancialYear = 0x1 and
[Date] > getdate()
Use the DATEADD and the DATEPART function, like this short example:
DECLARE #Date Datetime
SET #Date = '2013.01.08 00:00:00'
SELECT DATEADD(year,
CASE WHEN DATEPART(month, #Date) < 4
THEN 0
ELSE 1 END,
DATEADD(day, -DATEPART(day, #Date) + 1,
DATEADD(month, -DATEPART(month, #Date) + 4, #Date)))

Resources