Add days to pieced together date - sql

I have a database where, for some reason, the dates are put in like 1yymmdd. I have been asked to create a field in a query that adds 30 days to this date. I have transformed the date into a readable format by the following:
SUBSTRING(Datefield, 4, 2) + '/' + SUBSTRING(Datefield, 6, 2)
+ '/' + SUBSTRING(Datefield, 2, 2) AS LookLikeDate
I placed this in a view, and attempted to then:
DATEADD(dd,30, CONVERT(datetime, v.[LookLikeDate], 103)
I keep getting an error that says
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
I then attempted to define in my View statement so that this field would be datetime from the start:
CONVERT(datetime, SUBSTRING(Datefield, 4, 2) + '/'
+ SUBSTRING(Datefield, 6, 2) + '/'
+ SUBSTRING(Datefield, 2, 2), 103) AS LookLikeDate
When I got an error in that definition, to where I couldn't use the view at all, I changed the datetime to Char(8), which gave me the same varchar error I got previously.
Am I going about this wrong, and is there a way to add these days to this rediculous date format?

Just to add 30 days you can do
SELECT DATEADD(dd, 30, RIGHT(datefield, 6)) NewDate
FROM table1
To add 30 days and convert back to that format use
SELECT '1'+ CONVERT(VARCHAR(6), DATEADD(dd, 30, RIGHT(datefield, 6)), 12) NewDate
FROM table1
If you were to have following sample data
| DATEFIELD |
|-----------|
| 1130801 |
| 1130812 |
| 1120827 |
Then the output of two above mentioned queries would be
| NEWDATE |
|----------------------------------|
| August, 31 2013 00:00:00+0000 |
| September, 11 2013 00:00:00+0000 |
| September, 26 2012 00:00:00+0000 |
and
| NEWDATE |
|---------|
| 1130831 |
| 1130911 |
| 1120926 |
respectively.
Here is SQLFiddle demo

Related

Dynamically calculate how many months have passed - SQL Server

I am trying to calculate how many months ago the date field was
I have a table
CREATE TABLE Date(
Date Date
);
INSERT INTO Date (Date)
VALUES ('05-01-18'),
('04-01-18'),
('03-01-18'),
('02-01-18'),
('01-01-18'),
('12-01-17'),
('11-01-17');
And a query
SELECT Date ,
MONTH(Date),
CASE WHEN MONTH(Date) = MONTH(GETDATE()) Then 'Current Month'
WHEN MONTH(Date) = MONTH(GETDATE()) -1 Then '1 Month Ago'
WHEN MONTH(Date) = MONTH(GETDATE()) -2 Then '2 Month Ago'
ELSE 'n/a' END AS [Months Ago]
FROM Date
Which gives me the correct result:
| Date | | Months Ago |
|------------|----|---------------|
| 2018-05-01 | 5 | Current Month |
| 2018-04-01 | 4 | 1 Month Ago |
| 2018-03-01 | 3 | 2 Month Ago |
| 2018-02-01 | 2 | n/a |
| 2018-01-01 | 1 | n/a |
| 2017-12-01 | 12 | n/a |
| 2017-11-01 | 11 | n/a |
But is there anyway to create this dynamically instead of keep having to write case expressions. So if anyone add's more dates in the future this will just work without having to add more cases?
You exactly want datediff():
select datediff(month, date, getdate()) as num_months_ago
datediff() counts the number of month boundaries between two dates. So, Dec 31 is "one month before" Jan 1. This appears to be the behavior that you want.
I don't see an advantage to putting this in a string format.
In case you do want this to have a string format:
SELECT D.[Date],
DATEPART(MONTH,D.[Date]) AS [Month],
CASE WHEN V.DD = 0 THEN 'Current Month'
WHEN V.DD = 1 THEN '1 Month Ago'
ELSE CONVERT(varchar(4), V.DD) + ' Months ago' END AS MonthsAgo
FROM [Date] D
CROSS APPLY (VALUES(DATEDIFF(MONTH, D.[Date], GETDATE()))) V(DD);
I, however, agree with Gordon, SQL Server isn't really the palce to do that type of formatting. :)

SQL Server: DATEADD bypass dates based on the other table

I have two tables
tbl_date1
date_str | int_add
12/1/2016 | 5
12/2/2016 | 2
12/4/2016 | 4
tbl_date2 (Dates to be bypassed)
date_bpass
12/3/2016
12/4/2016
Result:
date_str | int_add | final_date
12/1/2016 | 5 | 12/8/2016
12/2/2016 | 2 | 12/6/2016
12/4/2016 | 4 | 12/8/2016
I want the query to return the final_date column value wherein the final_date is the DATEADD of the date_str and int_add but should not include
the dates present in tbl_date2.
Thank You
Here is one way
SELECT date_str,
int_add,
Dateadd(dd, int_add + add_count, date_str)
FROM tbl_date1 a
OUTER apply (SELECT Count(1)
FROM tbl_date2 b
WHERE b.date_bpass BETWEEN Dateadd(dd, 1, a.date_str) AND Dateadd(dd, a.int_add, a.date_str)) cs (add_count)
Live Demo

How to update a table with 2 random values, check in and check out dates/columns

In SQL Server how can I update a LibraryTtable with 3 random values, that follow a sequence of books in a lib.
The library system has to calculate fines, based on 3 factors checkout, allowed duration (books 30 days, mags 7 days), and finally checkin date.
For e.g.
First a Col1 -> Check-Out Date then based on a random NEWID()) % 30 days col2 -> Check-in Date and Col3 -> Originally allowed Duration (can be 7 to 30)
I can do this,
UPDATE [dbo].LibraryTtable
SET Check-Out = DATEADD(DAY, ABS(CHECKSUM(NEWID()) % 370), '2015-02-01')
but how do I hold that in a temp variable and add a random range within a span of 30 days for the check-in date
I can get the random values independently, but I don't know how to store and use them sequentially together.
I would write an UPDATE query via the CTE.
Sample data
DECLARE #LibraryTable TABLE (CheckOut date, CheckIn date, AllowedDuration int, ActualDuration int);
INSERT INTO #LibraryTable (CheckOut, CheckIn, AllowedDuration, ActualDuration) VALUES
(GETDATE(), GETDATE(), 30, 0),
(GETDATE(), GETDATE(), 30, 0),
(GETDATE(), GETDATE(), 30, 0),
(GETDATE(), GETDATE(), 30, 0),
(GETDATE(), GETDATE(), 30, 0);
Query
WITH
CTE
AS
(
SELECT
CheckOut
,CheckIn
,ActualDuration
,ABS(CHECKSUM(NEWID())) % 370 AS RandomNumber370
,ABS(CHECKSUM(NEWID())) % 30 AS RandomNumber30
FROM #LibraryTable
)
UPDATE CTE
SET
CheckOut = DATEADD(day, RandomNumber370, '2015-02-01')
,CheckIn = DATEADD(day, RandomNumber370 + RandomNumber30, '2015-02-01')
,ActualDuration = RandomNumber30
;
Result
SELECT *
FROM #LibraryTable;
+------------+------------+-----------------+----------------+
| CheckOut | CheckIn | AllowedDuration | ActualDuration |
+------------+------------+-----------------+----------------+
| 2015-09-07 | 2015-09-10 | 30 | 3 |
| 2015-11-25 | 2015-12-16 | 30 | 21 |
| 2015-06-16 | 2015-06-24 | 30 | 8 |
| 2015-11-25 | 2015-12-07 | 30 | 12 |
| 2015-03-25 | 2015-03-29 | 30 | 4 |
+------------+------------+-----------------+----------------+

Query to Convert Varchar HH:MM to Integer Minutes in SQL Server 2008

I am having a table in SQL Server where there is a column name TimeSpent Datatype Varchar(25). It basically stores Time as HH:MM Format.
As per the requirement now i want that it gives me actual timespent in Minutes i.e. 01:00 gives me 60, 01:30 -> 90.
Please help me to write the query in SQL Server 2008 , so that will convert Varchar (HH:MM) into Minutes(integer).
Try
SELECT LTRIM(DATEDIFF(MINUTE, 0, TimeSpent))
FROM yourtable
Given
| TIMESPENT |
-------------
| 00:12 |
| 01:05 |
| 10:00 |
Output:
| MINUTES |
-----------
| 12 |
| 65 |
| 600 |
Here is SQLFiddle
This will solve your issue. Please refer to SQLFiddle
select cast(left(TimeSpent, charindex(':',TimeSpent,0)-1) as int)*60+
cast(right(TimeSpent, len(TimeSpent)-charindex(':',TimeSpent, 0)) as int)
from test
SELECT top 1 (substring(CONVERT(VARCHAR(5), TimeSpent, 108), 1, 2) * 60 + substring(CONVERT(VARCHAR(5), TimeSpent, 108), 4, 2)) as minutes from test

SQL: Comparing Dates with only Month and Year columns

I have a table MonthlyShipments that looks like:
partnumber | quantity | month | year |
part1 | 12 | 6 | 2011 |
part1 | 22 | 5 | 2011 |
part1 | 32 | 4 | 2011 |
part1 | 42 | 3 | 2011 |
part1 | 52 | 2 | 2011 |
I want to sum the quantities of the past 3 months, excluding the current month. My where clause currently looks like:
where
MonthlyShipments.Month <> MONTH(GETDATE()) AND
CAST(
(CAST(MonthlyShipments.Month as nvarchar(2)) +
'-01-' +
CAST(MonthlyShipments.Year as nvarchar(4))) as DateTime)
> DATEADD(m, -4, GETDATE())
It works, but its ugly and insulting. Any advice on making it prettier? Much appreciate!
Not much better...
DATEDIFF(
month,
DATEADD(Year, MonthlyShipments.Year-1900,
DATEADD(Month, MonthlyShipments.Month-1, 0)
),
GETDATE()
) BETWEEN 1 AND 3
however the nested DATEADD can be made a computed and indexed column
ALTER TABLE MonthlyShipments ADD
ShipDate AS DATEADD(Year, MonthlyShipments.Year-1900,
DATEADD(Month, MonthlyShipments.Month-1, 0)
)
which gives
WHERE DATEDIFF(month, ShipDate, GETDATE()) BETWEEN 1 AND 3
Can you add a date column? If you need to do date calculations and you don't want things to get ugly this is probably going to be a requirement. Even a computed column would work...
Then you can just do something like this:
WHERE datecolumn < DATEADD(month, -3, GETDATE())
You can convert your month+date to date and then compare it with current date:
WHERE DATEDIFF(m,CONVERT(DATE, [month]+'/01/'+[year],101), GETDATE())
BETWEEN 1 AND 3
Or as it was said by others you can create a new computed column that holds date type
If you have a (year,month) index, this will make use of it, I think:
FROM MonthlyShipments ms
WHERE ( ms.year = YEAR(GetDate())
AND ms.month BETWEEN MONTH(GetDate())-3
AND MONTH(GetDate())-1
)
OR ( ms.year = YEAR(GetDate())-1
AND ms.month BETWEEN 12 + MONTH(GetDate())-3
AND 12 + MONTH(GetDate())-1
)
Not looking much prettier though.