Convert SQL Server date to DB2 date - sql-server

Here is db2 date format
1190707 - CYYMMDD
I would like to be able to convert a SQL Server DATE to this format
I found out i can use
SELECT FORMAT(GETDATE(), 'yyMMdd')
but problem now is to get the 1st character which i have no idea what it is

The C is a century digit. And it seems to be based on the 20th century, thus years starting with 19. For years starting with 20, the century digit is one and for the 20th century the century digit is omitted.
This should do the trick
DECLARE #DateToConvert AS DATE
SELECT #DateToConvert = GETDATE()
--SELECT #DateToConvert = DATEADD(year, -100, GETDATE())
SELECT
CAST(
CONCAT(
CAST((DATEPART(YEAR, #DateToConvert)/1000) AS INT)-1,
FORMAT(#DateToConvert, 'yyMMdd')
) AS BIGINT)

I believe this works
SELECT FORMAT(GETDATE(), 'yyyyMMdd') - 19000000

Related

Check if date falls within Month and Year range

If a user selects a range such as:
Start: November 2016
End: September 2017,
I want to include all results that fall within the range of 2016-11-01 to 2017-09-30.
I tried concatenating together the year, month, and day, however the issue comes that not all months have the same last day. While I know all months start on day 01, a month's end day can be 28, 29, 30, or 31.
Is there a way to do this without constructing the date? SqlServer 2008 doesn't have the EOMONTH function, and I feel like anything more complex than that is not the right solution. I would like to avoid this:
WHERE
DateCol >= '2016' + '-' + '11' + '-01' AND
DateCol <= '2017' + '-' + '09' + '-30'
It really seems to me that the easiest and best answer is to go from the first of the beginning month to the first of the month after the ending month, and make the second comparison not inclusive.
In other words, instead of this:
WHERE
DateCol >= '2016' + '-' + '11' + '-01' AND
DateCol <= '2017' + '-' + '09' + '-30'
simply this:
WHERE
DateCol >= '2016' + '-' + '11' + '-01' AND
DateCol < '2017' + '-' + '10' + '-01'
There is a faster way to do so :
DECLARE #minDate DATE
DECLARE #maxDate DATE
SET #minDate = XXXXX
SET #maxDate = YYYYY
-- Get the first day of the month minDate.
SET #minDate = CONVERT(datetime,CONVERT(varchar(6),#minDate,112)+'01',112)
-- Get the last day of the month minDate.
SET #maxDate = CONVERT(datetime,CONVERT(varchar(6),#maxDate,112)+'01',112)
SET #maxDate = DATEADD(day, -1, DATEADD(month, 1, #maxDate))
SELECT * FROM myTABLE WHERE DateCol >= #minDate AND DateCol <= #maxDate
Or :
SELECT * FROM myTABLE
WHERE DateCol >= CONVERT(datetime,CONVERT(varchar(6),XXXXX,112)+'01',112)
AND DateCol <= DATEADD(day, -1, DATEADD(month, 1, CONVERT(datetime,CONVERT(varchar(6),YYYYY,112)+'01',112)))
Use syntax like CONVERT(datetime,'20170930',112) or CONVERT(datetime,'09-30-2017',110) for XXXXX and YYYYY rather than '2017-09-30' that use SQL Server implicit convertion from char to datetime (rely on the server configuration : can be hazardous!!!)).
Using this syntax is faster because #minDate and #maxDate do not need any evaluation. So that indexes can be used directly...
Otherwise a scalar function that will simulate the eomonth() behaviour could be usefull...
You could use following select statement to get last date of any month (and any year) by passing a field or date to it:
DECLARE #dtDate DATE
SET #dtDate = '09/25/2016'
SELECT CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#dtDate)+1,0)) AS DATE) AS LastDay_AnyMonth
Please provide some example data and desired result and I will update my answer further.
Here you go:
DECLARE #YourTable TABLE (YourData DATE);
INSERT INTO #YourTable VALUES
('2016-11-01'),
('2016-09-05'),
('2017-03-03'),
('2017-11-11'),
('2017-12-14'),
('2017-09-30');
WITH CTE AS (
SELECT YourData
FROM #YourTable
WHERE YEAR(YourData) =2016 AND MONTH (YourData) >= 11
)
SELECT YourData
FROM #YourTable
WHERE YEAR(YourData) =2017 AND MONTH (YourData) <= 9
UNION ALL
SELECT YourData
FROM CTE;
There is no need to know the end of the month (28 or 30 or 31).
For 2008, you can simply convert the string
Example
Select Date1=convert(date,'November 2016')
,Date2=dateadd(DAY,-1,dateadd(MONTH,1,convert(date,'September 2017')))
Returns
Date1 Date2
2016-11-01 2017-09-30
So the WHERE would be somthing like this
...
Where DateCol between convert(date,'November 2016')
and dateadd(DAY,-1,dateadd(MONTH,1,convert(date,'September 2017')))
A useful construct for performing date-based operations is to make use of a Date Dimension table. You are creating a lookup table that is populated with a lot of information about dates over a large span of time. You can then query the table based on the information that you do have. The table is small enough so that it does not impose significant performance concerns.
In your particular case, you have the month and year. You would plug that into the date dimension table to get the first of the month from the beginning month and the last of the month from the ending month. You now have a time range to search over without any complex logic or calculations on the fly.
Aaron Bertrand explains it in depth here: https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/

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 Query to find the last day of the month in 6 months time

I am trying to write a bit of SQL that will give the last day of the month in 6 months time.
E.g. if I have of a date of inspection 15-07-2015 I want the next inspection date to be 31-01-2016
The date of inspection could be any day of any month
Any advise would be appreciated.
if i understand. that's it
declare #d date = '2015-07-15'
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#d)+7,0))
If you are using SQL Server 2012+ you can use the eomonth function to get the last day of a month:
declare #d date = '2015-07-15'
select eomonth(#d,6)
result: 2016-01-31
The function takes a date and an optional integer that specifies the number of months to add to the date parameter.
try this
declare #FindLastDay datetime
set #FindLastDay=CONVERT(varchar(10),DATEADD(M,6,'2015-07-15'),120)
SELECT CAST(DATEADD(ms, -3, DATEADD(mm, DATEDIFF(m, 0, #FindLastDay) + 1, 0)) as DATE)
output:
2016-01-31
Select DateAdd(D, Day(DateAdd(Month, 7, '2015-07-15')) * -1, DateAdd(M, 7, '2015-07-15'))
Yields the answer you expect.

SQL query not returning all rows

I have a table in SQL Server which has many rows, with a created_date column. This column has rows starting from the year 2006.
I want to get all the rows which were created in and before February, 2015. This stored procedure has a parameter #month. It should select all the rows based on the #month value entered.
Here is my query:
select *
from products
where 1=1
and year(created_date) <= 2015
and month(created_date) <= #month
But this query returns only the records which were created in and before February month of previous years excluding records which were created in other months of 2014 (e.g., 2014-03-17, 2014-05-05 are excluded).
I have to get a new date based on the #month entered. Suppose I entered month July, I want to have condition "where created_date < 2015-07-31". So I can do something like this,
So I have changed my query,
declare #date datetime
set #date = CAST((2015 + '-' + #month + '-' + 28) as datetime)
select *
from products
where 1=1
and year(created_date) <= 2015
But this query returns 1905-08-08 00:00:00.000 and I want to get 2015-02-28 00:00:00.000 and also I have to find total number of days based on the #month entered so that I can pass that number to CAST((2015 + '-' + #month + '-' + 28) as datetime) instead of 28.
Just use a single date and specify that the created_date column must be less than that date:
declare #newestDate datetime = '2015-03-01'
select *
from products
where created_date < #newestDate
Note that I set the date to be the 1st March but in the query I use < rather than <=. This will cope with a created_date value including a time component, e.g. 2015-02-28 23:59:59
To generate the value of "February of previous year", you may actually be wanting to use the current month of last year, if so, your date would be:
declare #newestDate datetime =
DATEADD(year, -1, DATEADD(month, DATEDIFF(month, 0, GETDATE())+1, 0))
This would then work next month (i.e. March) and would give your query a rolling month.
Always compare date/time fields to a single value where possible -- this is best for performance as well. You can "round" dates with DATEADD and DATEDIFF.
DECLARE #startOfNextMonth DATETIME;
SELECT #startOfNextMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + 1, 0);
select * from products where 1=1 and created_date < #startOfNextMonth;
String manipulation to convert dates is also possible, but tends to perform worse and is tricky to get right. This technique applies in general if you want to "round" to years, minutes, 15-second periods, etcetera, which is much harder with strings.
If you can, rewrite your stored procedure to not take a #month parameter but an absolute value that your clients calculate -- it's more general and tends to be easier to work with. Your query then simply reduces to
select * from products where 1=1 and created_date < #limit;
Of course, if you must use a #month, you can construct this offset in the stored procedure itself:
DECLARE #limit DATETIME =
DATEFROMPARTS(DATEPART(YEAR, GETDATE()), #month, 1)
;
This takes advantage of DATEFROMPARTS, which was introduced with SQL Server 2012. For previous versions, reliably constructing a date is considerably messier. There are many wrong ways to do it that will break if the regional settings are set to something unexpected. DATEADD is again of assistance:
DECLARE #limit DATETIME =
DATEADD(MONTH, (DATEPART(YEAR, GETDATE()) - 1900) * 12 + #month - 1, 0)
;
These are not the only methods to construct datetime values, but string manipulation is in any case tricky (because the only reliable format that will not break under regional settings is YYYYMMDD, no dashes).
In this question: Create a date with T-SQL you will see how to construct an sql-server date data type given a certain year and month. Suppose you call that 'my_date'.
You will then be able to do the following:
SELECT * FROM products WHERE created_date < my_date

TSQL query for Week Comparison

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)

Resources