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
Related
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
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
table:
--duedate timestamp
--submissiondate timestamp
--blocksreq numeric
--file clob
--email varchar2(60)
Each entry is a file which will take blocksreq to accomplish. There are 8 blocks allotted per day (but could be modified later). before i insert into the table, i want to make sure there are enough blocks to accomplish it in the timeframe of NOW() and #duedate
I was thinking of the following, but i think i am doing it wrong:
R1 = select DAY(), #blocksperday - sum(blocksreq) as free
from table
where #duedate between NOW() and #duedate
group by DAY()
order by DAY() desc
R2 = select sum(a.free) from R1 as a;
if(R2[0] <= #blocksreq){ insert into table; }
pardon the partial pseudocode.
SQL FIDDLE: http://sqlfiddle.com/#!2/5bda5
warning: My sql fiddle has garbage code... as i dont know how to make a lot of test cases. nor set the duedate to NOW()+5 days
Something like this? (wasn't sure how partial days were handled so ignored that part)
CREATE TABLE `DatTable` (
`duedate` datetime DEFAULT NULL,
`submissiondate` datetime DEFAULT NULL,
`blocksreq` smallint(6) DEFAULT NULL
)
SET #duedate:='2012-10-15';
SET #submissiondate:=CURRENT_TIMESTAMP;
SET #blocksreq:=5;
INSERT INTO DatTable(duedate,submissiondate,blocksreq)
SELECT #duedate,#submissiondate,#blocksreq
FROM DatTable AS b
WHERE duedate > #submissiondate
HAVING COALESCE(SUM(blocksreq),0) <= DATEDIFF(#duedate,#submissiondate)*8-#blocksreq;
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.
I have a log table with a date field called logTime. I need to show the number of rows within a date range and the number of records per day. The issue is that i still want to show days that do not have records.
Is it possible to do this only with SQL?
Example:
SELECT logTime, COUNT(*) FROM logs WHERE logTime >= '2011-02-01' AND logTime <= '2011-02-04' GROUP BY DATE(logTime);
It returns something like this:
+---------------------+----------+
| logTime | COUNT(*) |
+---------------------+----------+
| 2011-02-01 | 2 |
| 2011-02-02 | 1 |
| 2011-02-04 | 5 |
+---------------------+----------+
3 rows in set (0,00 sec)
I would like to show the day 2011-02-03 too.
MySQL will not invent rows for you, so if the data is not there, they will naturally not be shown.
You can create a calendar table, and join in that,
create table calendar (
day date primary key,
);
Fill this table with dates (easy with a stored procedure, or just some general scripting), up till around 2038 and something else will likely break unitl that becomes a problem.
Your query then becomes e.g.
SELECT logTime, COUNT(*)
FROM calendar cal left join logs l on cal.day = l.logTime
WHERE day >= '2011-02-01' AND day <= '2011-02-04' GROUP BY day;
Now, you could extend the calendar table with other columns that tells you the month,year, week etc. so you can easily produce statistics for other time units. (and purists might argue the calendar table would have an id integer primary key that the logs table references instead of a date)
In order to accomplish this, you need to have a table (or derived table) which contains the dates that you can then join from, using a LEFT JOIN.
SQL operates on the concept of mathematical sets, and if you don't have a set of data, there is nothing to SELECT.
If you want more details, please comment accordingly.
I'm not sure if this is a problem that should be solved by SQL. As others have shown, this requires maintaining a second table that contains the all of the individual dates of a given time span, which must be updated every time that time span grows (which presumably is "always" if that time span is the current time.
Instead, you should use to inspect the results of the query and inject dates as necessary. It's completely dynamic and requires no intermediate table. Since you specified no language, here's pseudo code:
EXECUTE QUERY `SELECT logTime, COUNT(*) FROM logs WHERE logTime >= '2011-02-01' AND logTime <= '2011-02-04' GROUP BY DATE(logTime);`
FOREACH row IN query result
WHILE (date in next row) - (date in this row) > 1 day THEN
CREATE new row with date = `date in this row + 1 day`, count = `0`
INSERT new row IN query result AFTER this row
ADVANCE LOOP INDEX TO new row (`this row` is now the `new row`)
END WHILE
END FOREACH
Or something like that
DECLARE #TOTALCount INT
DECLARE #FromDate DateTime = GetDate() - 5
DECLARE #ToDate DateTime = GetDate()
SET #FromDate = DATEADD(DAY,-1,#FromDate)
Select #TOTALCount= DATEDIFF(DD,#FromDate,#ToDate);
WITH d AS
(
SELECT top (#TOTALCount) AllDays = DATEADD(DAY, ROW_NUMBER()
OVER (ORDER BY object_id), REPLACE(#FromDate,'-',''))
FROM sys.all_objects
)
SELECT AllDays From d