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).
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 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)
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)))
I have a table that has a TASK_START_DATE and TASK_FINISH_DATE Columns of type datetime
I need help with a query that returns all Tasks when the Task: (date = just the date - I think I can do a conversion to the date from datetime on SQL 2008R2, it works fine)
- is within 2 weeks previous of the current date or two weeks after the current date.
Similarly I also need the records whose TaskEnd values are within 2 weeks previous or two weeks before
I've been trying things like which would get tasks where the start date is within the two previous weeks, but I have to do the same for TASK_FINISH_DATE and I think my and's and or's are all jumbled up, any help is appreciated.
Convert(Date, TASK_START_DATE) <= Convert(Date, DateAdd(ww, -2, GetDate()))
Short version:
How do I correctly write a query that combines all records with the TASK_START_DATE OR TASK_END_DATE within two weeks in the future or past, i.e.
Select Task_ID, TASK_NAME, TASK_START_DATE, TASK_END_DATE
where
???
You can add days to your date for comparision:
Select * from Table
Where column between getdate()-14 and getdate()+14
You don't need to use "Convert" function. "GetDate" function returns datetime value and your columns' types are datetime. You can add day number directly like this:
Select * from Table
Where (TASK_START_DATE between getdate() - 14 and getdate() + 14)
or (TASK_FINISH_DATE between getdate() - 14 and getdate() + 14)
You can declare variables or have the comparison dates right in the where clause. I use GETDATE() to get the date/time for right now as it returns a DATETIME object. Then I use DATEADD to adjust it for days, months, years, etc, and then you have to convert it to a DATE before sticking it in a variable of type DATE. Note in the DATEADD method I pass in the adjustment type (D = days), then adjust it + or - 14 days.
Alternatively you could just use 14 days ago to the minute if you don't do the DATE conversions...you'd have to remove the converts from the variable declarations as well as the where clause. Depends on the results you want though.
DECLARE #twoWeeksAgo DATE = CONVERT(DATE, DATEADD(D, -14, GETDATE()));
DECLARE #twoWeeksAhead DATE = CONVERT(DATE, DATEADD(D, 14, GETDATE()));
SELECT
Task_ID,
TASK_NAME,
TASK_START_DATE,
TASK_END_DATE
FROM
TABLE
WHERE
CONVERT(DATE, TASK_START_DATE) BETWEEN #twoWeeksAgo AND #twoWeeksAhead
OR CONVERT(DATE, TASK_END_DATE) BETWEEN #twoWeeksAgo AND #twoWeeksAhead
Also note that the BETWEEN operator in the WHERE clause is inclusive, meaning it will include records where the TASK_START_DATE is equal to the dates held by the variables. If you wanted to exclude records with the same value as #twoWeeksAhead, for example, you would have to use something like
WHERE
(CONVERT(DATE, TASK_START_DATE) >= #twoWeeksAgo
AND CONVERT(DATE, TASK_START_DATE) < #twoWeeksAhead)
OR (CONVERT(DATE, TASK_END_DATE) >= #twoWeeksAgo
AND CONVERT(DATE, TASK_END_DATE) < #twoWeeksAhead)