I have a simple report that some users can run to check that we have received data from an external source. It counts the minutes since the last line was updated where INS_TIME is the time that the interface inserted the data.
Code below.
select minute( now()-ins_time ) as LastUpdateMinutes
from p_electro
order by ins_time desc limit 1
This works well and is used in a Crystal Report. However i am trying to make another one for a different table with a little extra complexity. I copied the above code and added to it as below.
select minute( now()-ins_time ) as LastUpdateMinutes
from p_treats
where location like '%e5%' and creator is null
order by ins_time desc limit 1
This criterion should basically indicate that the row was inserted by the interface and then reveal the minutes since the last one was entered. However when i run it, it runs successfully but i get a NULL returned (as below).
LastUpdateMinutes
-----------------
| NULL |
I was expecting to see thousands of minutes given we haven't received any data since 13.05.17 at 11am.
This works fine for the first table and has been in use for years.
To add some context, our data clerk runs this report twice a day and reports if the time in minutes is longer than 20 minutes. With the second table, we have not received data for 5 days (thanks to measures put in place after this cyber-attack) and it wasn't flagged up until the light bulb ignited in my head that this was probably affected.
I want to create another report for this table that we can add to the clerks daily checks and learn of missing data sooner
Anyone have any advice on why the second example doesn't work but the first example does? And how to fix it?
I have tried multiple syntax along the lines of:
SELECT
datediff(now(), ins_time) AS DiffDate
FROM
p_treats
WHERE
location LIKE 'e5%' and
creator is null
ORDER BY ins_time DESC
LIMIT 1
Which actually works to pull back the number of days and:
SELECT
timediff(now(), ins_time) AS DiffDate
FROM
p_hdtreatment
WHERE
hpwhere LIKE 'e5%' and
creator is null
ORDER BY ins_time DESC
LIMIT 1
Which returns the hours and this might actually have to be what we use, but i wanted to make it a little more accurate.
Thanks in advance
Try this.
SELECT TIMESTAMPDIFF(MINUTE, ins_time, now()) AS LastUpdateMinutes
from p_treats
where location like '%e5%'
and creator is null
order by ins_time desc limit 1
Checkout ->
MySQL TimeStampDiff
Side Note:
minute() used as it is in the first "working" example, I believe is giving you wrong answers.. minute() only pulls the Minute part of a date/time string out. Eg. SELECT MINUTE('2008-02-03 10:05:03') yields 5
Assuming "ins_time" is of data type "TimeStamp" or "DateTime", If the result of MINUTE(now() - ins_time) is greater then 1 hour, your answer is wrong. I would need to test this more to be sure.
Related
Please consider the following query:
SELECT submitted_time FROM jobs WHERE timediff(NOW(), submitted_time) < '24:00:00'
My hope is for this to return all rows that have a "submitted_time" column containing a timestamp that was within the last 24 hours, However I am receiving the following results:
2017-01-18 14:58:34
2017-01-16 14:58:34
If I run the query SELECT NOW() I get 2017-01-25 18:58:32
Which appears to be correct.
What is stranger still is that I have more recent rows in the DB such as:
2017-01-24 15:17:13
Which are not being returned.
I hope I have made a glaringly obvious error that someone can point out, rather than beginning the descent into madness.
Just to be clear, the simplest and probably most performant way to handle this is (as per the link I provided in the comment)
SELECT submitted_time FROM jobs WHERE submitted_time > DATE_ADD(NOW(), INTERVAL -1 DAY);
This should be all jobs submitted literally within the last 24 hours at the moment the query is issued.
This might not be important to you for this query, but whenever you apply functions to columns in your table, any indexes you might have can not be used, because the database must run the function(s) on each value in the table before it can perform a comparison.
Using this method you figure out what the comparable datetime needs to be and mysql will use an index on submitted_time for the comparison, assuming that column is indexed appropriately.
I have a table that has a column that is called scores and another one that is called date_time
I am trying to find out for each 5 minute time increment how many I have that are above a certain score. I want to ignore the date portion completely and just base this off of time.
This is kind of like in a stats program where they display your peak hours with the only difference that I want to go is detailed as 5 minute time segments.
I am still fairly new at MySQL and Google seems to be my best companion.
What I have found so far is:
SELECT id, score, date_time, COUNT(id)
FROM data
WHERE score >= 500
GROUP BY TIME(date_time) DIV 300;
Would this work or is there a better way to do this.
I don't think your query would work. You need to do a bit more work to get the time rounded to 5 minute intervals. Something like:
SELECT SEC_TO_TIME(FLOOR(TIME_TO_SEC(time(date_time))/300)*300) as time5, COUNT(id)
FROM data
WHERE score >= 500
GROUP BY SEC_TO_TIME(FLOOR(TIME_TO_SEC(time(date_time))/300)*300)
ORDER BY time5;
I'm reasonably new to Access and having trouble solving what should be (I hope) a simple problem - think I may be looking at it through Excel goggles.
I have a table named importedData into which I (not so surprisingly) import a log file each day. This log file is from a simple data-logging application on some mining equipment, and essentially it saves a timestamp and status for the point at which the current activity changes to a new activity.
A sample of the data looks like this:
This information is then filtered using a query to define the range I want to see information for, say from 29/11/2013 06:00:00 AM until 29/11/2013 06:00:00 PM
Now the object of this is to take a status entry's timestamp and get the time difference between it and the record on the subsequent row of the query results. As the equipment works for a 12hr shift, I should then be able to build a picture of how much time the equipment spent doing each activity during that shift.
In the above example, the equipment was in status "START_SHIFT" for 00:01:00, in status "DELAY_WAIT_PIT" for 06:08:26 and so-on. I would then build a unique list of the status entries for the period selected, and sum the total time for each status to get my shift summary.
You can use a correlated subquery to fetch the next timestamp for each row.
SELECT
i.status,
i.timestamp,
(
SELECT Min([timestamp])
FROM importedData
WHERE [timestamp] > i.timestamp
) AS next_timestamp
FROM importedData AS i
WHERE i.timestamp BETWEEN #2013-11-29 06:00:00#
AND #2013-11-29 18:00:00#;
Then you can use that query as a subquery in another query where you compute the duration between timestamp and next_timestamp. And then use that entire new query as a subquery in a third where you GROUP BY status and compute the total duration for each status.
Here's my version which I tested in Access 2007 ...
SELECT
sub2.status,
Format(Sum(Nz(sub2.duration,0)), 'hh:nn:ss') AS SumOfduration
FROM
(
SELECT
sub1.status,
(sub1.next_timestamp - sub1.timestamp) AS duration
FROM
(
SELECT
i.status,
i.timestamp,
(
SELECT Min([timestamp])
FROM importedData
WHERE [timestamp] > i.timestamp
) AS next_timestamp
FROM importedData AS i
WHERE i.timestamp BETWEEN #2013-11-29 06:00:00#
AND #2013-11-29 18:00:00#
) AS sub1
) AS sub2
GROUP BY sub2.status;
If you run into trouble or need to modify it, break out the innermost subquery, sub1, and test that by itself. Then do the same for sub2. I suspect you will want to change the WHERE clause to use parameters instead of hard-coded times.
Note the query Format expression would not be appropriate if your durations exceed 24 hours. Here is an Immediate window session which illustrates the problem ...
' duration greater than one day:
? #2013-11-30 02:00# - #2013-11-29 01:00#
1.04166666667152
' this Format() makes the 25 hr. duration appear as 1 hr.:
? Format(#2013-11-30 02:00# - #2013-11-29 01:00#, "hh:nn:ss")
01:00:00
However, if you're dealing exclusively with data from 12 hr. shifts, this should not be a problem. Keep it in mind in case you ever need to analyze data which spans more than 24 hrs.
If subqueries are unfamiliar, see Allen Browne's page: Subquery basics. He discusses correlated subqueries in the section titled Get the value in another record.
I am trying to do some basic estimating of how long users spend on a site. I have a simple polling script in javascript that hearbeats out to a php script. I'm trying to do the following in one sql statement:
calculate the difference between now and the last updated_on field (which is a datetime field ) and add it to the current active_time field (which is just an integer)
Then update the updated_on to reflect that the record has been updated
This is the sql I'm trying to use;
UPDATE login_log
SET active_time = active_time + ( SELECT TIME_TO_SEC( TIMEDIFF( NOW(), updated_on ) ) ),
updated_on = NOW()
WHERE user_id = ? && session_id = ? AND status = 'active'
Question 1 - I'm assuming I can update updated_on and still use it to calc the difference and not have a race condition, but can someone confirm or tell me that doesn't work?
Question 2 - I must be doing something else wacky because after abit, the active_time is way off as in it thinkgs it's been going for hours when it's only been 20 minutes. Not really scope of this quesiton, but if anyone sees anything quickly that is wrong, I'd appreciate knowing ....
TIA
This seems like the wrong way to go about this. I would simplify it having two fields, created and updated_on, which I would call last_updated. To calculate the current time on the site you would simply subtract the created value from the current time. Presumably, you want some permanent record as well. That comes from the last_updated field, which is updated each time a request from the user is seen (including your heartbeat). You simply update it with the current time. The difference between created and last_updated becomes your permanent record of the time on site.
select (SELECT power FROM newdb.newmeter where date(dt)=curdate() order by dt desc limit 1)
-(select Power from newdb.newmeter where date(dt)=(select date(subdate(now(), interval weekday(now()) day))) limit 0,1) as difference;
The above query is part of my prog which gives me difference in data being stored from day 1 of the week to the current day of the week. Those queries individually works fine as below, and returns:
SELECT power FROM newdb.newmeter where date(dt)=curdate() order by dt desc limit 1;
result: 941690 current time
select Power from newdb.newmeter where date(dt)=(select date(subdate(now(), interval weekday(now()) day))) limit 0,1;
result 93242.4 at the start of the week (or day for today as its monday)
But as soon as I run the difference query which is just the difference between above two that result in : 848447.8515625
This seems just really strange don't understand whats wrong with it? Please help.
You don't order by dt in your second query, looking for power at the start of week. Which means you are selecting undefined record that happens to have matching date. For a simple select the table is usually sorted by insert order, but it can change when optimizer thinks it can run a query faster using some other order. Basically, if you don't define order you don't care about order.
How many decimal places do you want in the answer? Use DECIMAL(7,1) for Power (I assume you want one decimal place) instead and see what you get.
I tend to avoid floats/doubles as the approximate values can get you into trouble.