Find the rate for given date from mysql table - mysql

I have a table:
adate pdt_id pdt_rate
2017-10-02 5 20
2017-10-05 5 25
2017-10-07 5 23
2017-10-11 5 20
I have to find the rate of product with pdt_id 5 for between dates 2017-10-01 and 2017-10-10
For 2017-10-01 there is no rate in table so I take the lesser date like 2017-09-30 (no record), 2017-09-29 (no record) and so on (unfortunately no record). So I turn the bigger date than 2017-10-01 is 2017-10-02 (yes, there is a record) so I stop the searching and finalize as
2017-10-01 rate is 20
Now find the next date 2017-10-02, there is record and is 20
2017-10-02 rate is 20
Following the similar criteria I got
2017-10-03 rate is 20
2017-10-04 rate is 20
2017-10-05 rate is 25
....
2017-10-10 rate is 23
So my question is How to Find the rate for given date if the date exist other wise take the rate of lesser date and if the lesser date is not exist find the rate of next bigger date?
Finally we get rate for all dates(from start date to end date).
How can I achieve this?
$begin = new DateTime('2017-10-01');
$end = new DateTime('2017-10-10');
$daterange = new DatePeriod($begin, new DateInterval('P1D'), $end);
foreach($daterange as $date){
$dateval = $date->format("Y-m-d");
// here I want find the rate for each date
}

Here is one method:
select t.*
from t
order by (adate <= '2017-10-01') desc
abs(datediff(adate, '2017-10-01'))
limit 1;

Related

MySQL getting the closest row available based on date

I'm measuring different kind of events daily and get records looking like that:
id measurement_date value
111 2020-12-01 21:30:00 100
111 2020-12-02 22:00:12 110
111 2020-12-03 21:35:17 80
114 2020-12-02 21:47:56 780
114 2020-12-04 21:55:47 700
....
Then I am having a query transforming the data to get the difference between 2 measurements.
I am running this transform on different windows of time (1 day, 7 days, 1 month).
For 1 day it is quite straightforward as I either have a measurement or if missing I have no intermediary data to compensate and therefore place a 0.
Here is the query I use:
SELECT id,
(ft.value - ft2.value) as progression,
FROM feed_table ft
JOIN feed_table ft2 on ft2.id = ft.id
AND date_format(ft2.date, '%Y-%m-%d') = date_format(date_sub(CURDATE(), interval 1 day), '%Y-%m-%d')
WHERE date_format(ft.date, '%Y-%m-%d') = date_format(CURDATE(), '%Y-%m-%d')
However for longer windows, like 7 days, for example, I would like to make use of the intermediary data if they exist.
Let's say I am measuring on the 7 days window between today 2020-12-08 and 7 days before 2020-12-01, but I only have the following measurements which are neither today nor 7 days ago but are still inside the 7 days window:
id measurement_date value
111 2020-12-02 21:30:00 200
111 2020-12-06 21:30:00 300
Then the query above with a 7D interval and the right settings should return :
id progression
111 100
(max date value - min date value in the 7 days window)
I was thinking of aggregating by user_id and using the min-max date in the having close, but my self-join wouldn't work anymore...
Any idea?

mysql query for elapsed time per day

I have such this table as below and I trying to calculate the elapsed time for which the value "relay" is to 1 per day by creating a view.
id, date, time, dateandtime,timestamp,sensor,temperature,humidity,status
xx 15/03/2018 11:39:00 15/03/2018 11:39:00.0 15/03/2018 11:39 sensor1 23 41 0
xx 15/03/2018 11:40:00 15/03/2018 11:40:00.0 15/03/2018 11:39 sensor2 23 41 1
Here is the query that I come with, however the output is not as except for the past or previous day...
select date,time,TIMESTAMPDIFF(MINUTE,MAX(Date), timestamp) as minutes FROM temperaturedata where relay = 1 group by date
Here is the results:
date time minutes
2018-03-15 11:39:00 699
2018-03-16 11:01:00 661
Some clarifications, I am trying to get how long per day and hour the status has been set to 1.
something like:
date, starttime, endtime, minutes;
As starttime would be when the first of instance to 1 appears and endtime the last time, minutes the total amount of minutes for which the status was to 1.
hope it make a bit more sense. :)
Any guidance would be more than welcome.
THanks.
J.

Selecting time-based data

What I am trying to achieve is grab data from the database, depending on the time.
For example, I may have multiple prices for an item, and I would like the new price to be effective based on the time and date. So I can schedule price changes in advance.
id link_id datetime price
-------------------------------------------
2 11 2016-11-03 00:00:00 1020
3 11 2016-11-03 01:00:00 1050
4 11 2016-11-03 03:00:00 1090
Let's say the time is 2016-11-03 00:59:00, when a user queries the db they will se the price-1020. But when they query the db a minute later at 2016-11-03 01:00:00 they should get price-1050.
Have tried this WHERE datetime < UTC_TIMESTAMP(), however this does not solve my problem. Also it only needs to select one entry, this selects multiple.
Is there a way MySQLi can do this?
If you are only looking for one item, I would expect something like this:
select p.*
from prices p
where p.item_id = $item_id and -- however you are representing items
p.datetime <= now() -- or UTC Timestamp if that is how the date/time is represented
order by p.datetime desc
limit 1;
I could speculate that "link_id" refers to "items".

Get peak amount of active rows from all time

I have the following problem. I have a mysql table that has a startdate and and enddate. Each row is considered active between those dates. Some rows are no longer active, but have been active in the past. For example the following table:
id start end
1 2014-11-11 00:00:00 2015-01-31 23:59:59
2 2014-09-25 10:16:14 2015-06-01 23:59:59
3 2013-12-24 00:00:00 2014-12-01 23:59:59
4 2014-08-13 00:00:00 2016-01-31 23:59:59
5 2013-09-11 00:00:00 2014-09-10 23:59:59
My actual table has way more data than that. Now I need to know what the peak amount of concurrent active rows is without knowing when that peak actually occured. How would I do this in SQL? In the example 4 rows are active at the same time (1-4, not 5) in the time between 2014-11-11 and 2015-01-31 23:59:59. The actual peak time doesn't matter to me as much as the peak amount itself.
Thanks for your help
Find different timestamps of interrest using UNION ALL, count number of active tasks at these timestamps:
select ts, (select count(*) from tablename t2
where timestamps.ts between t2.start and t2.end) as count
from (select start as ts
from tablename
union all
select end
from tablename) as timestamps
order by count desc
limit 1
Finally order descending and pick the highest value only!
(From a non MySQL user, so some details may be wrong... Please comment if that's the case and I'll edit!)

Generating a MySQL hourly breakdown from current timestamp

I'm afraid this is probably a very embarrassingly easy question - but my mind is just completely stuck at this hour.
I have a table that stores the number of activities carried out by different people, and the time it took place in.
I want to create a report that accepts the person's name as a parameter, and show the number of activities per hour for that person during each of the previous 24 hours starting from current timestamp (now()).
Right now,
SELECT hour(TimeStamp), activities FROM tbl1
WHERE timestamp >= DATE_SUB(NOW(), INTERVAL 24 HOUR) AND Name = ?
GROUP BY hour(timestamp)
only returns to me those hours when any activity was present. However, I want a complete 24 hour breakdown with zero for when there was no activity.
i.e. I'm getting
Hour | No. of Activities
1 | 34
4 | 22
9 | 86
but I want
Hour | No. of Activities
1 | 34
2 | 0
3 | 0
4 | 22
5 | 0
... etc.
How do I do this?
(The order of hours in the example is irrelevant)
You can create a hourly table, and do a LEFT JOIN
create table hourly
(
/* hour is not a reserved keyword */
hour smallint(2) not null default 0
);
insert into hourly values (0),(1).... until 24
SELECT
hourly.hour,
COALESCE(COUNT(activities),0) AS "No of Activities"
FROM hourly
LEFT JOIN tbl1 ON hourly.hour=hour(tbl1.TimeStamp)
WHERE
tbl1.timestamp>=DATE_SUB(NOW(), INTERVAL 24 HOUR) AND
tbl1.Name=?
GROUP BY hourly.hour
ORDER BY hourly.hour;