mysql average latest 5 rows - mysql

I have table:
describe tests;
+-----------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-----------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| line_id | int(11) | NO | | NULL | |
| test_time | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| alarm_id | int(11) | YES | | NULL | |
| result | int(11) | NO | | NULL | |
+-----------+-----------+------+-----+-------------------+-----------------------------+
And I execute query:
SELECT avg(result) FROM tests WHERE line_id = 4 ORDER BY test_time LIMIT 5;
which I want to generate average of 5 latest results.
Still something is not ok, because query generates average of all table data.
What can be wrong?

If you want the last five rows, then you need to order by the time column in descending order:
select avg(result)
from (select result
from tests
where line_id = 4
order by test_time desc
limit 5
) t

the guy before submitted something link that
for my it works
select avg( id ) from ( select id from rand limit 5) as id;

Only one result set will be returned because of the AVG function.

Related

LIMIT showing duplicate results

I can't figure out why this is happening. I have a table with the following columns:
+-------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------+------+-----+---------+----------------+
| adid | int(11) | NO | PRI | NULL | auto_increment |
| price | float | YES | | NULL | |
| categoryid | int(11) | YES | | NULL | |
| visible | tinyint(4) | YES | MUL | NULL | |
+-------------+------------+------+-----+---------+----------------+
There are 7 records in this table that are visible and have category set as 3. I do a simple query like this:
SELECT adid FROM ads as a
WHERE categoryid = 3
and visible = 1
order by price desc
limit 0, 5
I get the following adid's returned: 1,4,3,15,7
On the next page the query is:
SELECT adid FROM ads as a
WHERE categoryid = 3
and visible = 1
order by price desc
limit 5, 5
I get: 11,15
Maybe I am up too late, but why do I get 15 twice?
For the results to be stable and consistent you need to have any unique column to participate in sorting.
In this case it might be
ORDER BY price DESC, adid

MySQL - Select last data inserted in last 5 days skip missing records for days

I want to select the data that was inserted in the last 5 days, and if the rows are missing for that day then move on to the previous day, but it always have to return rows from the last 5 days.
The column which i'm trying to match is a DATETIME column
I've tried using this query
select * from `thum_{ROH}` where date >= NOW() - INTERVAL 5 DAY;
Now this return data from 2013-12-24 to 2013-12-22 because data on 2013-12-25 and 2013-12-26
is not available.
How can i modify the query to make it return the last 5 days data irrespective of missing rows. So in this case it will return data inserted on
2013-12-24
2013-12-23
2013-12-22
2013-12-19
2013-12-12
The days which are missing in between the dates above simply have no rows associated with them so they won't be returned.
I have also tried using
select distinct(date(date)), power from `thum_{ROH}` limit 5;
But this only selects some values in a specific date while skips on the rest. What i mean is that there are around 30 or more rows in each day which are present so the above query only returns around 2 or 3 rows per day.
I hope my question makes sense. I've been trying to find a solution without any success. Please provide any sort of advice on how can i achieve this. I would appreciate any help.
Thanks in advance,
Maxx
EDIT
Here is the table structure in question.
+-----------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+---------+-------+
| thumType | int(11) | NO | PRI | 0 | |
| timestamp | int(10) unsigned | NO | PRI | 0 | |
| rune | char(15) | YES | | NULL | |
| date | datetime | YES | | NULL | |
| destruction | decimal(15,2) | YES | | NULL | |
| restoration | decimal(15,2) | YES | | NULL | |
| conjuration | decimal(15,2) | YES | | NULL | |
| alteration | decimal(15,2) | YES | | NULL | |
| illusion | int(10) unsigned | YES | | NULL | |
| power | decimal(15,2) | YES | | NULL | |
| magicka | decimal(15,2) | YES | | NULL | |
| health | decimal(15,2) | YES | | NULL | |
+-----------------+------------------+------+-----+---------+-------+
You can do this with a join:
select t.*
from `thum_{ROH}` t join
(select distinct date
from `thum_{ROH}`
order by date desc
limit 5
) as date5
on t.date = date5.date;
EIDT:
The above works if we assume that there is no time component.
We can fix that problem by doing:
select t.*
from `thum_{ROH}` t join
(select distinct date(date) as thedate
from `thum_{ROH}`
order by date desc
limit 5
) as date5
on date(t.date) = date5.thedate;
Assuming that the 'date' column is of type date, then we can solve this with a subquery to get the 5 most recent non-blank dates and then only select rows from those days.
SELECT *
FROM tablename
WHERE date IN (
SELECT distinct date FROM tablename ORDER BY date DESC LIMIT 5
)

Selecting latest conversations from table containing private messages

I have a table containing personal messages from one user to another.
Here is the table structure:
mysql> describe pms;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| time | datetime | NO | | NULL | |
| from | int(11) | NO | | NULL | |
| from_ip | int(11) | NO | | NULL | |
| to | int(11) | NO | | NULL | |
| message | varchar(255) | NO | | NULL | |
| read | tinyint(4) | NO | | 0 | |
+---------+--------------+------+-----+---------+----------------+
I am creating a view which shows 10 latest conversations of a particular user id. As I want to find conversations, I thought of using GROUP BY from, to. This, however, returned duplicate rows (both from this user and to this user), and I also noticed that ordering does not work as it should.
In order to be able to properly order the results and thus select the 10 latest conversations, the groups should contain the latest row of the group instead of the first.
Here is the query I tried:
SELECT *
FROM `pms`
WHERE `from` = 1
OR `to` = 1
GROUP BY `from` , `to`
ORDER BY `id` DESC
LIMIT 10
Which gives the wrong row from the group, and therefore ordering by id (or time) gives a wrong order.
Any ideas how I could get it working?
This assumes that a conversation is defined by the from-to pair in either order, and that the latest conversation has the largest id:
SELECT least(`from`, `to`), greatest(`from`, `to`)
FROM `pms`
WHERE `from` = 1 OR `to` = 1
GROUP BY least(`from`, `to`), greatest(`from`, `to`)
ORDER BY max( `id`) DESC
LIMIT 10

MYSQL : Improving query perfomance on join with order by clause

I have two tables which contains the daily activities of a user . I have two join these tables and select top ten ids from this table .
Table 1 : buildlog
+----------------+------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------------+------+-----+---------+----------------+
| NAME | varchar(50) | YES | | NULL | |
| ID | int(11) | NO | PRI | NULL | auto_increment |
| DATE_AND_TIME | datetime | YES | | NULL | |
| COMMENT | mediumtext | YES | | NULL | |
+----------------+------------------------+------+-----+---------+----------------+
Number Of Rows : 276186
Table 2 : reports
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| r_id | int(10) | NO | PRI | NULL | auto_increment |
| id | int(15) | YES | UNI | NULL | |
| label | varchar(200) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
Number Of Rows : 134058
If I am using only join query with this two tables using id it comes very quickly .
Query 1:
select buildlog.id,reports.label from buildlog join reports on reports.id = buildlog.id limit 10\G
Query Time : 10 rows in set (0.01 sec)
If I add order by to get latest ten build ids,label it takes 1 to 2 minutes to execute .
Query 2 :
select buildlog.id,reports.label from buildlog join reports on reports.id = buildlog.id order by buildlog.id desc limit 10\G
Query Time : 10 rows in set (0.98 sec)
order by column is an primary key buildlog.id . So, It's already indexed why It takes more time to execute this query ? . Can anyone suggest how can I optimize this?
SELECT * FROM (
SELECT
buildlog.id,
reports.label
FROM
buildlog
JOIN
reports
ON
reports.id = buildlog.id
) AS myval_new
ORDER BY id DESC limit 10
The slow down comes because it is probably choosing to do the ordering before doing the join. Doing the order by in an outer query forces it to only order the selected items.

How to code this SELECT statment?

Given this table :
mysql> describe activity;
+---------------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+-------------+------+-----+---------+-------+
| user_id | varchar(16) | NO | | NULL | |
| login_time | int(11) | NO | | NULL | |
| last_activity_time | int(11) | NO | | NULL | |
| last_activity_description | text | YES | | NULL | |
| logout_time | int(11) | NO | | NULL | |
+---------------------------+-------------+------+-----+---------+-------+
5 rows in set (0.01 sec)
I want to select the most recent last_activity_time (standard Unix timestamp) for each user who is logged in (i.e has one or more rows where logout_time is not zer0).
I tried
SELECT user_id, login_time, MAX(last_activity_time)
FROM activity
WHERE logout_time="0";
...but that found only a single entry with two users logged in, probably because I am selecting for MAX(last_activity_time)
What I want is something like
SELECT all unique user_ids
SELECT each of those which has one or more entries where `logout_time` != 0
SELECT the maximum value of `logout_time` for each of those
all in one single SELECT statement. How can I do that?
SELECT user_id, MAX(logout_time)
FROM activity
WHERE logout_time <> "0"
GROUP BY user_id;