I have a table which includes the columns Season and Academic_Year. Academic_Year is type int. Season can be Spring, Summer or Fall.
Fall 2016 is from 1 Sep 2016 to 31 Dec 2016.
Spring 2016 is from 1 Jan 2017 to 31 Mar 2017 (not a typo - the Academic Year 2016 is from Sep 2016 to Aug 2017)
Summer 2016 is from 1 Apr 2017 to 31 Aug 2017
I need to select rows when getdate() is between a number of days before and after the start of the Season, in pseudo code
WHERE
( getdate() > 31/3/16 AND getdate() < 31/9/16 AND Season = 'Autumn' AND Academic_Year = 2016 )
OR ( getdate() > 31/9/16 AND getdate() < 31/1/17 AND Season = 'Spring' AND Academic_Year = 2016 )
OR ( getdate() > 31/12/16 AND getdate() < 31/4/17 AND Season = 'Summer' AND Academic_Year = 2016 )
My problem is creating the date for comparison with getdate(). I need to combine a string - '31/3/' - with an int - Academic_Year, and create a date.
The solution does not need to be efficient but it does need to work on 2008 and later sql server versions.
SQL will allow this conversion if you just concatenate the varchars and tell it to convert to date. For example:
declare #year int = 2016
declare #date varchar(10) = '3/31'
select cast(#date + '/' + cast(#year as varchar(4)) as date)
You have to cast the integer year to varchar to combine it with the other varchar, but you can then cast the entire thing to a date (or datetime) once you have a recognized date format.
You can form your date by doing by using concatenation of the string and year.
CONVERT(VARCHAR(4), Academic_Year) + '-03-31'
Once you have the date string you could use the date functions to manipulate it further if necessary.
WHERE (GETDATE() > CONVERT(VARCHAR(4),Academic_Year) + '-03-31'
AND GETDATE() < CONVERT(VARCHAR(4),Academic_Year) + '-09-30'
AND Season = 'Autumn') etc
worked for me. The trick was adding '-03-31' rather than preceeding with '31-03-'. Thanks #kicken
Related
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, ''))
I'm trying to figure out a way to query the last 12 completed months of data, so it would go up to last month and ignore this month.
I've done this before when the table had a date column, but this new table I'm working with separates the date into two month and year columns.
How would I go about this in SQL Server 2012?
Thanks in advance.
SAMPLE DATA:
CalendarYear CalendarMonth TotalSales
2014 3 35.00
2014 4 220.00
2015 2 243.00
2015 5 17.93
2015 6 216.36
2015 10 370.93
2015 12 350.00
2016 1 116.75
2016 2 13.78
DESIRED OUTPUT (assuming current time is in February 2016):
CalendarYear CalendarMonth TotalSales
2015 2 243.00
2015 5 17.93
2015 6 216.36
2015 10 370.93
2015 12 350.00
2016 1 116.75
I've assumed the Day part is always the 1st of the month.
WHERE
CONVERT(DATETIME, CalendarYear + '-' + CalendarMonth + '- 01') >= DATEADD(mm, -12, GETDATE())
The above assumes the columns are strings. Below I've done a version where the columns are numbers.
WHERE
CONVERT(DATETIME, CAST(CalendarYear AS NVARCHAR(4)) + '-' + CAST(CalendarMonth AS NVARCHAR(2)) + '-01') >= DATEADD(mm, -12, GETDATE())
You can just apply same code/logic to year and month you want data.
where to_date(year || month, 'YYYYMM')
between add_months(trunc(sysdate, 'MM'), -12) and trunc(sysdate)
I imported a table into SQL Server 2014 and I found that the date format is in BST and GST format. I want to create a view and change the whole column to SQL Server date type to perform operations. I don't mind truncating the time section.
Wed Apr 07 00:00:00 BST 1943
Tue Jan 08 00:00:00 GMT 1985
I was able to do it in Excel with the following formula but want to do it in SQL Server:
=IFERROR(DATEVALUE(MID(E2,9,2)&"-"&MID(E2,5,3)&"-"&RIGHT(E2,4)), "")
All I am looking for is
1943-04-07
1985-01-08
This solution assumes that every row in the source data follows the same format. If there are any fringe cases these will fail.
With SQL Server 2012, and higher, you have the handy DATEFROMPARTS function. This function returns a date when passed a year, month and day. These can be extracted with SUBSTRING and RIGHT from the source string.
Extracting the month number (1~12) is achieved by building an arbitrary date string (01-mmm-2000). This is cast into a date, from which the month number is extracted. Generally speaking I would't recommend using date strings in any format other than YYYY-MM-DD. However this avoids the use of a CTE, which OP was keen to do.
Example
/* Let's create some sample values to
* experiment with.
*/
DECLARE #Sample TABLE
(
DateVal VARCHAR(50)
)
;
INSERT INTO #Sample
(
DateVal
)
VALUES
('Wed Apr 07 00:00:00 BST 1943'),
('Tue Jan 08 00:00:00 GMT 1985')
;
/* Extracting the month number is achieved by first casting the 3 character month
* name as a full date, by appended a day and year. Then the month number is
* extracted from this.
*/
SELECT
s.DateVal,
SUBSTRING(s.DateVal, 9, 2) AS [Day],
MONTH(CAST('01-' + SUBSTRING(s.DateVal, 5, 3) + '-2000' AS DATE)) AS [Month],
RIGHT(s.DateVal, 4) AS [Year],
-- Reuse the values shown above.
DATEFROMPARTS(
RIGHT(s.DateVal, 4),
MONTH(CAST('01-' + SUBSTRING(s.DateVal, 5, 3) + '-2000' AS DATE)),
SUBSTRING(s.DateVal, 9, 2)
) AS [Date]
FROM
#Sample AS s
;
EDIT: The original solution contained a CTE, used to look up the month number from a 3 character month name. This has been replaced.
SELECT CONVERT(date, RIGHT(DateColumn, 4)+ '-' + RIGHT('0' + Convert(nvarchar, (Month(SUBSTRING(DateColumn, 5, 3) + '2016'))), 2) + '-' + SUBSTRING(DateColumn, 9, 2)) as dob
FROM MyTable
Your sample output doesn't match your input data. I think you meant 1985-01-08.
For a shorter solution, you can use CAST or CONVERT with style 107. It expects the string to be in the Mon dd, yyyy format:
SELECT CONVERT(datetime, SUBSTRING(DateColumn, 5, 6) + ', ' + RIGHT(DateColumn, 4), 107)
FROM MyTable
I have two dates say '2011-01-23' and '2015-11-29',
'2011-01-23' falls in first quarter of 2011 so 'Jan 2011'
'2015-11-29' falls in fourth quarter of 2015 so 'Oct 2015'
In SQL Server I want get all quarters in a select list.
e.g.
Input: #StartDate='2011-01-23' , #EndDate='2015-11-29'
Output:
Jan 2011
Apr 2011
Jul 2011
Oct 2011
Jan 2012
Apr 2012
Jul 2013
Oct 2013
Jan 2014
......
......
......
Jul 2015
Oct 2015
You can use a recursive CTE to generate the dates as follows:
declare #StartDate datetime
declare #EndDate datetime
select #StartDate='2011-01-23' , #EndDate='2015-11-29'
;With Quarters as (
select DATEADD(quarter,DATEDIFF(quarter,0,#StartDate),0) as dt
union all
select DATEADD(quarter,1,dt)
from Quarters
where dt < DATEADD(quarter,DATEDIFF(quarter,0,#EndDate),0)
)
select
--I'd usually keep them as dates at this point, but to match your requirement
CONVERT(varchar(3),dt,109) + ' ' + CONVERT(varchar(4),dt,120)
from Quarters order by dt
This also uses a couple of other tricks - it uses CONVERT with far too short target datatypes to quickly truncate the strings to just the parts that we want to keep - and it uses a DATEADD/DATEDIFF pair to quickly round a datetime value down to it's nearest interval boundary.
For SQL Server 2012, you could instead use FORMAT to produce the output string, but I've not experimented with that much so I'll leave that as an exercise...
Finally, I found the solution of my question..
WITH mycte AS
(
SELECT CAST('2011-01-01' AS DATE) DateValue
UNION ALL
SELECT DATEADD(Q,1,DateValue) FROM mycte WHERE DATEADD(Q,1,DateValue) < '2012-12-31'
)
SELECT CONVERT(varchar(3), DATENAME(MONTH,DateValue))+ ' ' +Convert(varchar(4),DATEPART(YYYY,DateValue)) FROM mycte OPTION (MAXRECURSION 0)
I am building a report which has the header field as PropertyStatementForHalfyear Ending :<Date>
So in the DATE field I need to put either May 28 or Nov 28 depending on the date the report Runs
Whats The logic I need to write ??
For example if I run the report today i.e. June 22, I need to display PropertyStatementForHalfyear Ending : 28 Nov 2013
if I run it in December 2013, I need to display PropertyStatementForHalfyear Ending : 28 May 2014
You could use something like this:
DECLARE #DateThreshold1 DATE = '20130528'
DECLARE #DateThreshold2 DATE = '20131128'
DECLARE #CurrentDate DATE = '20131201'
IF #CurrentDate > #DateThreshold2
SELECT CONVERT(VARCHAR(50), DATEADD(YEAR, 1, #DateThreshold1), 106)
ELSE IF #CurrentDate > #DateThreshold1
SELECT CONVERT(VARCHAR(50), #DateThreshold2, 106)
ELSE
SELECT CONVERT(VARCHAR(50), #DateThreshold1, 106)
For dates from 20130101 through 20130528, this will return 28 May 2013
For dates from 20130529 through 20131128, this will return 28 Nov 2013
For dates past 20131128, this will return 28 May 2014
You can easily package this up into a function or a SSRS code snippet
If you're not into IF/CASE statements, like me:
with dt as
(select CAST('2013-11-28' as datetime) dt) --dt becomes your datetime column.
, ymdt as (select
DATEPART(year, dt) y,
DATEPART(month, dt) m,
DATEPART(day, dt) d,
dt
from dt) --split into year, month and date for readability
select y, m, d, dt,
DATEADD(month, 5 + d/28 - (m + d/28) % 6, --add months depending on month and day
DATEADD(day, 28 - d --go to the correct day
, dt) --start calculation from dt (the sql date functions' parameter order has always baffled me)
) HalfYearEndDate
from ymdt
The SQL engine merges all of this into one big fat constant scan or scalar expression on your datetime column.
You should create a SQL or VB function for this if you need this in other reports and also so it doesn't clutter up your queries.
Also: Don't do text formatting in T-SQL unless absolutely necessary! Return a datetime column and do it in the report itself. The format you need to set on the textbox is "dd MMM yyyy" (without the quotes when using the designer).