How to select the beginning of the following April in SQL Server? - 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)))

Related

How can I write a query in SQL Server to capture prior month data?

My problem statement is trying to capture the data for the prior month, using the max(date) for the data set. For example if my MAX(DISCHARGE DATE) = APRIL, 12, 2020.
I would like my query to capture data from MARCH 1, 2020 to MARCH 31, 2020.
select [ENC_KEY_MAIN], MAX([Discharge Date]) AS LastActivity
from vw_HOME_CLINTIGRITY
group by [ENC_KEY_MAIN]
having MAX([Discharge Date]) < DATEADD(MM, -3, MAX([Discharge Date]));
You could use EOMONTH() and DATEADD() as
DECLARE #MXD DATE = (SELECT EOMONTH(MAX(Col), -1) FROM Table);
SELECT *
FROM Table
WHERE Col <= #MXD
AND
Col >= DATEADD(Day, -(DAY(#MXD)-1), #MXD);
Here is a db<>fiddle
declare #dt int = select month(max([Discharge Date]))-1 from vw_HOME_CLINTIGRITY
select [ENC_KEY_MAIN], DATENAME(MONTH,getdate()-29) AS LastActivity
from vw_HOME_CLINTIGRITY
where month([Discharge Date])=#dt

Get date from week and year - date must be first day of the year - sql

I have a query that converts week and year to date.
But it returns the exact date.
But what i want is, I need the date to be such a day, that is same as the first day of the year.
dateadd (week, PromisedWeek-1, dateadd (year, PromisedYear-1900, 0)) - 4 -
datepart(dw, dateadd (week, PromisedWeek-1, dateadd (year, PromisedYear-1900, 0)) - 4) + 1
Hypothetical example.
My current query does is:
If week is 4 and year 2017, returns 26-Sun-2017
My need:
If week is 4 and year 2017 and January 1st was a Wednesday, its should return 29-Wednesday-2017.
Hoping that you guys get what I am trying to explain.
I need the query to return such a date which has the same day as that of the current year's 1st day.
Unless I'm reading this wrong, you're making things too hard on yourself. Just do this:
declare #year int; set #year = 2017;
declare #week int; set #week = 4;
select dateadd(week, #week, dateadd(year, #year - 1900, 0))
Result:
2017-01-29 00:00:00.000
The inner dateadd() gives you the first day of the requested year (Jan 1), regardless of weekday. If it's a Wednesday, you'll get a Wednesday. This year, it's Sunday. The outer dateadd() then adds full weeks to that, so you end up with the same day of the week, just like you asked.
If that's not what you want, please explain how it needs to be more complicated.
This is pretty easy if you have a calendar table. A calendar table is a table that contains every date and its parts for a given range. I created mine for 2010 to 2020 with this code:
declare #start_dt as date = '1/1/2010';
declare #end_dt as date = '1/1/2020';
declare #dates as table (
date_id date primary key,
date_year smallint,
date_month tinyint,
date_day tinyint,
weekday_id tinyint,
weekday_nm varchar(10),
month_nm varchar(10),
day_of_year smallint,
quarter_id tinyint,
first_day_of_month date,
last_day_of_month date,
start_dts datetime,
end_dts datetime
)
while #start_dt < #end_dt
begin
insert into #dates(
date_id, date_year, date_month, date_day,
weekday_id, weekday_nm, month_nm, day_of_year, quarter_id,
first_day_of_month, last_day_of_month,
start_dts, end_dts
)
values(
#start_dt, year(#start_dt), month(#start_dt), day(#start_dt),
datepart(weekday, #start_dt), datename(weekday, #start_dt), datename(month, #start_dt), datepart(dayofyear, #start_dt), datepart(quarter, #start_dt),
dateadd(day,-(day(#start_dt)-1),#start_dt), dateadd(day,-(day(dateadd(month,1,#start_dt))),dateadd(month,1,#start_dt)),
cast(#start_dt as datetime), dateadd(second,-1,cast(dateadd(day, 1, #start_dt) as datetime))
)
set #start_dt = dateadd(day, 1, #start_dt)
end
select *
into Calendar
from #dates
Once you have a calendar table you can query for the correct weekday in the PromisedWeek
declare #PromisedYear as numeric
declare #PromisedWeek as int
set #PromisedYear = 2017
set #PromisedWeek = 4
select concat(date_day, '-', weekday_nm, '-', #PromisedYear)
from Calendar as c
where
weekday_id =
(select weekday_ID
from Calendar
where date_year = #PromisedYear
and day_of_year = 1
)
and datepart(week, date_id) = #PromisedWeek
and date_year = #PromisedYear
Turns out that January 1st 2017 was a Sunday and the 4th Sunday in 2017 was January 22nd, so the return is 22-Sunday-2017

Week start date and week end date calculated wrong

I have a query for calculating first and last date in the week, according to given date. It is enough to set #dDate and the query will calculate first (monday) and last date (sunday) for that week.
Problem is, that is calculating wrong and I don't understand why.
Example:
#dDate = 2019-10-03 (year-month-day).
Result:
W_START W_END
2019-09-25 2019-10-01
But it should be:
2019-09-30 2019-10-06
Why is that?
Query:
set datefirst 1
declare #dDate date = cast('2019-10-16' as date)
select #dDAte
declare #year int = (select DATEPART(year, #dDAte))
select #year
declare #StartingDate date = cast(('' + cast(#year as nvarchar(4)) + '-01-01') as date)
select #StartingDate
declare #dateWeekEnd date = (select DATEADD(week, (datepart(week, cast(#dDate as date)) - 1), #StartingDate))
declare #dateWeekStart date = dateadd(day, -6, #dateWeekEnd)
select #dateWeekStart W_START, #dateWeekEnd W_END
Days of the week are so complicated. I find it easier to remember that 2001-01-01 fell on a Monday.
Then, the following date arithmetic does what you want:
select dateadd(day,
7 * (datediff(day, '2001-01-01', #dDate) / 7),
'2001-01-01' -- 2001-01-01 fell on a Monday
)
I admit this is something of a cop-out/hack. But SQL Server -- and other databases -- make such date arithmetic so cumbersome that simple tricks like this are handy to keep in mind.

get last day of previous year from sybase ase

I need to set a where condition to the last date of previous year.
I looking for the solution using dateadd function but i can not figure it out. This code gives me the last day of current month. But how to get the last day of december last year '2015-12-31' of have tried different ways but it all gives me odd results.
declare #today datetime
select #today=getdate()
select convert(varchar(10), dateadd(dd, -day(dateadd(mm, 1, #today)),dateadd(mm, 1, #today)),101)
Assuming Sybase ASE, not ASA or IQ:
declare #lastyear smallint, #dec31 datetime
select #lastyear = datepart(year,getdate()) - 1
select #dec31 = convert(datetime, convert(char(4), #lastyear) + "1231")
select #dec31
This produces
--------------------------
Dec 31 2015 12:00AM
#lastyear contains 2015, the last year, then text "2015" is concatenaded into "20151231", which is the desired date in AAAAMMDD char format. Next step converts it into date, datetime or smalldatetime. #dec31 stores that result.
select convert(datetime, convert(varchar, datepart(year, getdate()) - 1 ) + '/12' + '/31')
Dec 31 2015 12:00AM
SELECT DATEADD(DD,-1,DATEADD(YEAR, DATEDIFF(YEAR, '', GETDATE())+1, ''))

SQL Server partitioning monthly data by weeks and calculating weekly weighted average based on month days of that week belong to

I have a table like this:
Month Value
2012-08-01 0.345
2012-09-01 0.543
2012-10-01 0.321
2012-11-01 0.234
2012-12-01 0.234
User inputs week range from '2012-09-29' to '2012-10-13'
Output should show results for all weeks in requested range and average values for each week with the following logic:
- if all weekdays are entirely in one month, just use monthly value for that month
- if weekdays are spread out over two months, calculate weekly value as average between those two months giving preference to the month that contains the most days of that week.
If someone can give me an idea how to do something like this in T-SQL that would be highly appreciated.
The last query is the example. The Calendar table is built on-request, but every database can do with a persisted Calendar table, on which you would filter the date range instead.
declare #tbl table (
Month datetime,
Value decimal(10,3));
insert #tbl select
'2012-08-01', 0.345 union all select
'2012-09-01', 0.543 union all select
'2012-10-01', 0.321 union all select
'2012-11-01', 0.234 union all select
'2012-12-01', 0.234;
declare #start datetime, #end datetime;
select #start = '2012-09-29', #end ='2012-10-13';
;with Calendar(TheDate,StartOfWeek,StartOfMonth) as(
select #start, #start+1-Datepart(dw,#start), #start-Day(#start)+1
union all
select TheDate+1, TheDate+1+1-Datepart(dw,TheDate+1),
TheDate+1-Day(TheDate+1)+1
from Calendar
where TheDate < #end
)
select case when #start > v.StartOfWeek
then #start else v.StartOfWeek end RangeStart,
case when #end < v.StartOfWeek+6
then #end else v.StartOfWeek+6 end RangeEnd,
cast(avg(m.value) as decimal(10,3)) [Average]
from Calendar v
join #tbl m on v.StartOfMonth = m.Month
group by v.StartOfWeek;
Output
RANGESTART RANGEEND Average
September, 29 2012 September, 29 2012 0.543
September, 30 2012 October, 06 2012 0.353
October, 07 2012 October, 13 2012 0.321
Your query would be something like this. The idea is find the first day of the next month DATEADD(mm, DATEDIFF(mm, 0, Month) + 1, 0. Calculate the number of days, and then you can get the monthly total, and calculate the average based on the difference between the first day of the current month and next month. (SQL syntax may need some clean up).
declare #startdate datetime
declare #enddate datetime
set #startdate = '2012-09-05'
set #enddate ='2012-10-13'
Select Monthtotal/DateDiff(d,Month,NextMonth)
FROM
(Select
Month, DATEADD(mm, DATEDIFF(mm, 0, Month) + 1, 0) NextMonth,
DateDiff(d,Month, DATEADD(mm, DATEDIFF(mm, 0, Month) + 1, 0) * Value as Monthtotal
FROM DatesTable
WHERE
#startdate >= Month and
#enddate <= DATEADD(mm, DATEDIFF(mm, 0, Month) + 1, 0))

Resources