I have a decent query working now but I need to find the max out of the results. The rssi field.
table layout
id - rssi, item, datetime
My query now is
select
id, rssi
from
table
where
item = 1 and dt > date_sub(now(), interval 1 minute)
I have tried several other answers from around here and they work fine if I do not use the date part but I want to run the query only on the latest entries.
If you want the most recent row:
select id, rssi
from table
where item = 1
order by dt desc
limit 1;
For performance, you want an index on (item, dt desc).
EDIT:
Based on your comment, that would be:
select id, rssi
from table
where item = 1 and dt > date_sub(now(), interval 1 minute)
order by rssi desc
limit 1;
You get the max rssi with max(rssi), as the function name suggests :-)
select max(rssi)
from table
where item = 1 and dt > date_sub(now(), interval 1 minute);
Related
I have a certain problem while trying to make an SQL. I have a table with the following format and data.
id
value
date
12
3
2020-06-01
12
4
2020-06-09
12
1
2020-06-20
5
4
2020-06-11
5
5
2020-06-17
My goal is to make something like that:
id
lower
higher
12
1
1
5
0
1
This looks for the value of the oldest row IN specific interval (ex. 100 days)and it compares it with all dates after that if their values are higher and lower and return the count.
I do have something that works but it requires more queries:
One to group take all ids with dates in the interval of xx days
SELECT id FROM table
WHERE date >= CURDATE() - INTERVAL 30 DAY GROUP BY id
ORDER BY id ASC;
And then I loop through each row and get its lower and higher values.
SELECT
*
FROM
(
SELECT
COUNT(*) AS higher, id
FROM
`table`
WHERE
id = 12 AND date > CURDATE() - INTERVAL 30 DAY AND value > (
SELECT value FROM table
WHERE table.date >= CURDATE() - INTERVAL 30 DAY AND id = 12
ORDER BY `table`.`date` ASC LIMIT 1
)
) AS t1,(
SELECT
COUNT(*) AS deteriorated_placements
FROM
`table`
WHERE
id = 12 AND date > CURDATE() - INTERVAL 30 DAY AND value < (
SELECT value FROM table
WHERE table.date >= CURDATE() - INTERVAL 30 DAY AND id = 12
ORDER BY `table`.`date` ASC LIMIT 1
)
) AS t2;
The problem with that is that I do around 40 more queries. I know it maybe is not a big issue but
Is there a way to somehow combine those 2 queries?
Use first_value():
select id,
sum(value < value_1) as lower,
sum(value > value_1) as higher
from (select t.*,
first_value(value) over (partition by id order by date) as value_1
from t
) t
group by id;
I have a table in MySQL with fields:
id - int;
date - datetime;
rating - decimal(3,2);
and so on, other fields are not necessary in this selection.
There are about 6000 rows in the table.
I have to get rows from the table that is ordered by rating ASC for the last 6 months and then other rows ordered by id ASC.
How can I do it?Will it work fast?
I would do something like this to achieve that:
select *
from tbl
order by case
when date >= DATE_ADD(curdate(), INTERVAL -6 MONTH) then
rating
else id
end ASC;
You need to make sure that all the records from the last 6 months come first in the result, and then worry about ordering by rating or id. You can do that by ordering on the boolean
date >= CURDATE() - INTERVAL 6 MONTH
first, and then on either rating or id as appropriate. For example:
SELECT *
FROM data
ORDER BY date >= CURDATE() - INTERVAL 6 MONTH DESC,
CASE WHEN date >= CURDATE() - INTERVAL 6 MONTH THEN rating
ELSE id
END
I have the following query:
SELECT * FROM event_incidents order by last_update desc limit 1;
What I want is to get the first row and check if the last_update time on that row is greater than 10 minutes from the current time.
You can try like this:
select * from event_incidents
where last_update >= (NOW() - INTERVAL 10 MINUTE)
ORDER BY last_update desc
LIMIT 1;
You can do this using aggregation and a comparison in the where. If you have an index on last_update then:
SELECT (case when MAX(last_update) >= date_sub(now(), interval 10 minute)
then 'recent'
else 'ancient'
end)
FROM event_incidents ;
I'm not sure what you want to return, so I made up "recent" and "ancient".
Note:
If you just want a flag on a single row being returned:
SELECT ei.*,
(last_update > date_sub(now(), interval 10 minute)) as RecencyFlag
FROM event_incidents
ORDER BY last_update desc
LIMIT 1;
I have a table with a timestamp col and around 100000 rows, how can I find the % of the total entries that have a timestamp in the last week? I can find the number of entries
SELECT count(*) c FROM table t WHERE timestamp_col > DATE_SUB(now(), INTERVAL 1 WEEK)
but how would I then work that back to a % of the total rows?
I can do this imperatively with 2 statements but am wondering if there is an SQL only solution?
You can actually do this easily. Here is a short way:
SELECT avg(timestamp_col > DATE_SUB(now(), INTERVAL 1 WEEK) )
FROM table t;
MySQL treats boolean values as integers with 1 being true and 0 being false.
The above is equivalent to:
SELECT sum(timestamp_col > DATE_SUB(now(), INTERVAL 1 WEEK) ) / count(*)
FROM table t;
I always have trouble with complicated SQL queries.
This is what I have
$query = '
SELECT id,
name,
info,
date_time
FROM acms_events
WHERE date_time = DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND active = 1
ORDER BY date_time ASC
LIMIT 6
';
I want to get up to 6 rows that are upcoming within the hour. Is my query wrong? It does not seem to get events that are upcoming within the next hour when I test it.
What is the correct syntax for this?
I'm going to postulate that you're looking at a group of records that contain a range of DATETIME values, so you probably want something more like this:
SELECT id,
name,
info,
date_time
FROM acms_events
WHERE date_time < DATE_ADD(NOW(), INTERVAL 1 HOUR)
AND date_time >= NOW()
AND active = 1
ORDER BY date_time ASC
LIMIT 6
Otherwise, your query is looking for records with a date_time of exactly "now + 1 hour". I'm assuming all your dates aren't specific to that particular second. ;)
To clarify a bit, DATE_ADD() and DATE_SUB() return exact timestamps, so your query above roughly translates to something like SELECT ... WHERE date_time = '2010-04-14 23:10:05' ORDER BY ..., which I don't think is what you want.
WHERE date_time = DATE_SUB(NOW(), INTERVAL 1 HOUR)
means date_time equals exactly now minus one hour, which would result in any record exactly one hour old.
Why not use
WHERE TIMEDIFF(date_time, NOW()) < '01:00:00'
AND date_time > NOW()