Want to find available month between two dates using sql server - sql-server-2008

I want the unique month between two date
like
#StartDate = '04-05-2013'
#EndDate = '26-12-2013'
I want the output like
5 6 7 8 9 10 11 12
I also want to use cursor with above output how to get this using sql server

Generally speaking, you may use a script like the following in order to obtain the values you are looking for. I can't understand whether you would need a single result set or not, so the script simply returns one result set for each month: feel free to modify it as you need, even by mixing the code with your (existing?) cursor-related script:
DECLARE #StartDate datetime = '2013-05-04'
DECLARE #EndDate datetime = '2013-12-26'
WHILE (#StartDate < #EndDate)
BEGIN
SELECT MONTH(#StartDate)
SET #StartDate = DATEADD(month, 1, #StartDate)
END
Also please note this is a starting point: for performance reasons, you may want to somehow consider reviewing the entire query.

If you only need months number then you can get the difference of months between two dates and increment it to get the result as shown below:
DECLARE #StartDateMonth int = DATEPART(mm, '2013-05-04')
DECLARE #EndDateMonth int = DATEPART(mm,'2013-12-26')
WHILE (#StartDateMonth <= #EndDateMonth )
BEGIN
SELECT #StartDateMonth
SET #StartDateMonth = #StartDateMonth + 1
END

Related

Declare variable in a SQL statement

I wonder if is possible to create variables inside a sql select query.
Explanation in the following sample, where we select the news from a city published /or updated in the past month (or older):
set #monthBack = 1; -- one month back in time
set #cityName = "Berlin"; -- take a city name
select n.title, coalesce (n.releaseDate, n.updateDate) as news_date
from news as n
inner join with cities as c on c.id = n.cityid
where
c.name = #cityName and
year(coalesce (n.releaseDate, n.updateDate)) =
year(current_date - interval #monthBack month)
month(coalesce (n.releaseDate, n.updateDate)) =
month(current_date - interval #monthBack month)
order by coalesce (n.releaseDate, n.updateDate)
If a publication date is not defined, the news date will be the updated date.
So, I would like to replace the repetition of the coalesce (n.releaseDate, n.updateDate) by a specific variable that is specific to the concrete select statement...
Is it possible in the mysql database?
PS.
As the "problem" is more about sql syntax and code readability, I would like to resolve it just by modifying the sql code, but not applying to external tools or creating additional objects like views or tables (does not worth such complexity for some syntactic optimization)
I can think of many ways to resolve your problems but I'm not sure wich one is the best.
You could do a ";With" subquery to determine the value of "coalesce (n.releaseDate, n.updateDate)" and then use it in the query below.
Or use a stored procedure ou function wich recive the right parameters
You could do a view on your table news and add a column wich is the value of "coalesce (n.releaseDate, n.updateDate)"
Or you can also do something like :
set #monthBack = 1; -- one month back in time
DECLARE #Query NVarchar(Max),
#NewsDate NVARCHAR(MAX)
SET #NewsDate = coalesce (n.releaseDate, n.updateDate) -- Determine the value here
SET #Query =
'select n.title, '+#NewsDate+' as news_date
from news as n
inner join with cities as c on c.id = n.cityid
where
c.name='Berlin' and
year('+#NewsDate+') =
year(current_date - interval #monthBack month)
month('+#NewsDate+')) =
month(current_date - interval #monthBack month)
order by '+#NewsDate
execute sp_executesql #Query

SQL Server 2008 DATEPART function

I need a query to update a column of DATETIME type by adding 2 hours only in Hours column using the DATEPART() function. Please help me out.
My query looks like this:
UPDATE logdetails
SET user_logouttime = DATEPART(HH, user_logouttime) + 2
WHERE id = (SELECT TOP 1 id FROM logdetails
WHERE user_id = 10
ORDER BY user_logintime DESC)
It just updates the time column with default value whereas I want only hours to be updated instead of entire time. Say if it's 2013-12-05:09:45:58, I want it to be 2013-12-05:11:45:58.
declare #no_hours int
set #no_hours = 2
declare #a datetime
set #a='2013-12-05 09:45:58'
select dateadd(HOUR, #no_hours, #a) as new_time_added
fiddle demo

How to get list of records from table where the time difference found using DATEDIFF function between 2 variables that are select queries themselves?

SET #startdate = (select LOG_TIME from log.time where sender='Japan' and receiver ='USA' and code=158);
SET #enddate = (select LOG_TIME from log.time where sender='Japan' and receiver ='USA' and code=189);
select * from log.time where DATEDIFF(minute, #startdate, #enddate) >= 10;
Here I want to use 2 variables (#startdate and #enddate) which are populated with multiple entries coming from the select queries used .
And for the last line , I want the select query to return a list of records where the DATEDIFF function is greater than or equal to 10 minutes by using these 2 variables with multiple values .
P.S I am using the Squirrel SQL Client 2.3 )
The issue is I have no idea if it is possible to use multiple values for variables.
Also please advise or provide any solution to the above issue such that the query works in the end.
You can't use variables this way.
Now it's hard to tell for sure not seeing your table schema and sample data but you should be able to do what you want using JOIN with a query like this
SELECT l1.*
FROM log.time l1 JOIN log.time l2
ON l1.sender = l2.sender
AND l1.receiver = l2.receiver
AND l1.code = 158
AND l2.code = 189
WHERE l1.sender = 'Japan'
AND l1.receiver = 'USA'
AND DATEDIFF(minute, l1.log_time, l2.log_time) >= 10
If you were to provide a table schema, sample data and desired output, then it'll be possible to test your query

No TimeDiff function in T-SQL?

I have created a new column called DesiredTimeOfFileCreation of type time(7); this will indicate at what time the data is to be extracted to an export file.
Let's suppose it is set to 6:00:00. I then have a SQL agent job scheduled at 6:00 (probably every 30 minutes), but it might run at 6:00:05 or even 6:01. I want to select all rows where the DesiredTimeOfFileCreation is less than 30 minutes ago.
Does someone already have a user-defined TimeDiff function? Or is there an easy alternative that I'm missing?
As Martin mentioned above, I need to handle the midnight wrap-around.
This seems overly complicated. The code below seems to work if one time is one hour before midnight, and one is within an hour after. Would be nice to make it more generic. I think the only way to do that would be to make up a dummy date, which I may experiment with next.
The reason I'm passing a date in the unit test is that I will be passing a casted version of GetUTCDate() as a parm:
ALTER FUNCTION TimeDiffMinutes
(
#FirstTime time(7),
#SecondTime time(7)
)
RETURNS int
AS
BEGIN
/*
Unit Test:
select dbo.TimeDiffMinutes('13:31',cast ('2013-06-10 13:35' as time)), -- simple test
dbo.TimeDiffMinutes('23:55',cast ('2013-06-10 00:05' as time)) -- test midnight wrap-around
select dbo.TimeDiffMinutes('23:55',cast ('2013-06-10 00:05' as time)) -- test midnight wrap-around
*/
-- Declare the return variable here
DECLARE #resultMinutes int
DECLARE #Hour int
-- although we can compare two times, the problem is that if one time is 11:55 and the other is 00:05, we want to show 10 minutes difference.
-- We cannot add 24 hours to a time, because that would be an invalid value
Set #Hour = datePart(hour,#SecondTime)
if (#Hour <= 0)
begin
-- increase both times by an hour so we can compare them, 23:55 will wrap around to 01:55
Set #FirstTime = DateAdd(hour,+1,#FirstTime)
Set #SecondTime = DateAdd(hour,+1,#SecondTime)
end
SET #resultMinutes = DATEDIFF(Minute,#FirstTime,#SecondTime)
-- Return the result of the function
RETURN #resultMinutes
END
NOTE: This code shows that you cannot go past 24 hours in a time; it just wraps back around (with no error!):
declare #FirstTime time(7)
SET #FirstTime = '23:05'
print #FirstTime
Set #FirstTime = DATEADD(HOUR,1,#FirstTime)
print #FirstTime
Improved version, using an arbitrary date.
ALTER FUNCTION TimeDiffMinutes
(
#FirstTime time(7),
#SecondTime time(7)
)
RETURNS int
AS
BEGIN
/*
Unit Test:
select dbo.TimeDiffMinutes('13:31',cast ('2013-06-10 13:35' as time)), -- simple test
dbo.TimeDiffMinutes('23:55',cast ('2013-06-10 00:05' as time)) -- test midnight wrap-around
select dbo.TimeDiffMinutes('23:55',cast ('2013-06-10 00:05' as time)) -- test midnight wrap-around
*/
-- Declare the return variable here
DECLARE #resultMinutes int
DECLARE #Hour int
DECLARE #FirstDate datetime
DECLARE #SecondDate datetime
Set #FirstDate = CAST('2001-01-01 ' + Convert(varchar(12),#FirstTime) as DateTime)
Set #SecondDate = CAST('2001-01-01 ' + Convert(varchar(12),#SecondTime) as DateTime)
-- although we can compare two times, the problem is that if one time is 11:55 and the other is 00:05, we want to show 10 minutes difference.
-- We cannot add 24 hours to a time, because that would be an invalid value
Set #Hour = datePart(hour,#SecondDate)
if (#Hour <= 0)
begin
-- increase both times by an hour so we can compare them, 23:55 will wrap around to 01:55
Set #SecondDate = DateAdd(day,+1,#SecondDate)
end
SET #resultMinutes = DATEDIFF(Minute,#FirstDate,#SecondDate)
-- Return the result of the function
RETURN #resultMinutes
END
This is how I will use the function. We store the local time that an airport wants an extract file in a table. Then we will use SQL agent or BizTalk to poll every 30 minutes looking for work to do. AirportCode is a column in the table, and we have our own crazy function that converts for timezones.
select *,
dbo.TimeDiffMinutes(
DesiredFileCreationTimeLocal,
cast(dbo.LocationLocalTimeFromAirportCode(AirportCode,GETUTCDATE()) as time)
) as 'MinutesAgo'
from TransactionExtractDistribution
where dbo.TimeDiffMinutes(
DesiredFileCreationTimeLocal,
cast(dbo.LocationLocalTimeFromAirportCode(AirportCode,GETUTCDATE()) AS time)
) < 30
This will probably work for me:
WHERE DATEDIFF(Minute,DesiredFileCreationTimeLocal,cast(GETDATE() as time)) < 30
I had to research what happened if you pass a Time as a variable to the DateDiff function.
It seems to work, the only trick is then how to pass two times to it.
My real-world scenario is more complex, because we are dealing with different locations in different time zones, so there will some UTC conversions added to the above.

TSQL - Calculating datediff in a query and setting a value?

Using SQL Server 2008, I want to calculate the timespan, in seconds, that has occurred between two times.
The start date, is the timestamp of the last occurance of where a specific ID exists (if the filter is true), get the time from that timestamp record, and do a DATEDIFF() against the current processing time and return a value, #LastEventTimespan, in seconds.
DECLARE #CurrentProcessTime DATETIME
DECLARE #LastEventTimespan DATETIME
SET #CurrentProcessTime = GetDate()
-- find the timespan since the last session event
-- DATEDIFF ( datepart , startdate , enddate )
SELECT MAX(PageVisitEventID) AS LastPageVisitEventID, #LastEventTimespan = DATEDIFF(second , DateAdded , #CurrentProcessTime )
FROM PageVisitEvents
WHERE UserID = #UserID
GROUP BY LastPageVisitEventID
I figured I could get the MAX ID of the filter and process accordingly but am unable to set the #LastEventTimespan, however trying to assign a value when doing data-retrieval is a no-no.
How can I get around this?
Thanks.
I guess you want something like this.
DECLARE #LastEventTimespan INT
SELECT TOP 1 #LastEventTimespan = DATEDIFF(SECOND, DateAdded, GETDATE())
FROM PageVisitEvents
WHERE UserID = #UserID
ORDER BY PageVisitEventID DESC
This will calculate the difference in seconds between DateAdded for the highest value of PageVisitEventID for a given user and the current DateTime. I changed the data type of #LastEventTimespan to INT because it probably makes more sense when dealing with seconds.
You can replace the SELECT statement with this one:
SELECT TOP 1
#LastEventTimespan = DATEDIFF(second , DateAdded , #CurrentProcessTime )
FROM PageVisitEvents
WHERE UserID = #UserID
ORDER BY PageVisitEventID desc
I've done such queries many times and never had problems.