Count and group by issue - mysql

I have that table :
forum:
_____________________________________________________________
|match_static_id| comment | timpstamp | user_id |
|_______________|___________|______________________|__________|
| 1 | Hi | 2013-07-10 12:15:03 | 2 |
| 1 | Hello | 2013-07-09 12:14:44 | 1 |
|_______________|___________|______________________|__________|
the working query is:
select forum.match_static_id,
count(forum.match_static_id) 'comment_no'
Group By forum.match_static_id
But what if I want to have:
select forum.match_static_id,
count(forum.match_static_id) 'comment_no',
forum.timestamp
Group By forum.match_static_id
It will give the same result as the previous query but with a value of timestamp for each record
I want this value to be the most recent timestamp could that be done?

Just use the max() function.
select forum.match_static_id,
count(forum.match_static_id) 'comment_no',
max(forum.timestamp)
Group By forum.match_static_id
Here's a list and explanation of the available aggregate functions.

How about this:
select forum.match_static_id,
count(forum.match_static_id) 'comment_no',
max(forum.timestamp)
Group By forum.match_static_id

Related

MySQL - count records and list people

I have table with results:
date | user_id | content
-----------------------------------------
2017-01-14 | 1 | lorem
2017-01-02 | 2 | dsfdf
2017-01-02 | 1 | asfds dsfsda
2017-01-27 | 3 | sdfdfds fsdf
And I want count row for all users and receive result like this:
user_id | count
-----------------------------------------
1 | 2
2 | 1
3 | 1
I try:
select distinct(user_id), count(*) from aso_repairs where date like '2017-01-%'
But this don't work ;-( Any help?
use the GROUP BY clause:
SELECT
user_id,
count(user_id)
FROM aso_repairs
WHERE
date LIKE '2017-01-%'
GROUP BY user_id
You shouldn't use count(*), at least in MySQL 3.23 this is far more expensive than count(somecolumn) although it yields the same result.
Add the missing group by clause:
SELECT
user_id, COUNT(*)
FROM
aso_repairs
WHERE
date LIKE '2017-01-%'
GROUP BY user_id;
Also, the like operator won't let you use any index if there was one on the date column. Consider providing the actual date boundaries:
SELECT
user_id, COUNT(*)
FROM
aso_repairs
WHERE
date BETWEEN '2017-01-01' AND '2017-01-31'
GROUP BY user_id;

Select AVG of a column and a single specific row

feedback table
-------------------------------
|rating|feedback|feedback_date|
-------------------------------
| 5 | good | 1452638788 |
| 1 | bad | 1452638900 |
| 0 | ugly | 1452750303 |
| 3 | ok | 1453903030 |
-------------------------------
desired result
average_rating | rating | feedback | feedback_date
2.25 | 3 | ok | 1453903030
Is it possible (in a single query) to select the average of one column and also one specific row from the table?
For example, i'd like to retrieve the average of the column rating and the most recent row as a whole.
I tried the following, and also with the ORDER BY direction as DSC but they both just gave me the average_rating and the first row in the table.
SELECT AVG(f.rating) AS average_rating, f.* FROM feedback f ORDER BY feedback_date ASC
SELECT * FROM feedback NATURAL JOIN (
SELECT AVG(rating), MAX(feedback_date) feedback_date FROM feedback
) t
See it on sqlfiddle.
you can do it with a sub query like this
SELECT AVG(f.rating) AS average_rating, t1.* FROM feedback f inner join (select * from feedback order by feedback_date asc limit 1 ) t1 on true
You can put a subquery in the SELECT clause, and calculate the average in the subquery.
SELECT (SELECT AVG(rating) FROM feedback) AS avg_rating, feedback.*
FROM feedback
ORDER BY feedback_date DESC
LIMIT 1

How to get the value of a row with Max aggregation function?

I have a table for comments :
+----------+---------------------+----------+
| match_id | timestampe | comment |
+----------+---------------------+----------+
| 100 | 2014-01-01 01:00:00 | Hi |
| 200 | 2014-01-01 01:10:00 | Hi1 |
| 300 | 2014-01-01 01:20:00 | Hi2 |
| 100 | 2014-01-01 01:01:00 | Hello |
| 100 | 2014-01-01 01:02:00 | Hello1 |
| 200 | 2014-01-01 01:11:00 | hey |
+----------+---------------------+----------+
I want to get the following information from the table
SELECT match_id, max(timestampe) as maxtimestamp, count(match_id) as comments_no
FROM comments
GROUP BY match_id
order by maxtimestamp DESC
The previous explanation is working great but the problem is when I want to get the comment of the maxtimestamp.
How can I get the latest comment of each match (the comment of the maxtimestamp) using the most optimized query?
You can do it this way.
This is pretty optimal too.
SELECT c.comment, m.*
FROM
comments c
JOIN
(
SELECT t.match_id, max(t.timestampe) as maxtimestamp, count(t.match_id) as comments_no
FROM comments t
GROUP BY t.match_id
) m on c.match_id = m.match_id and c.timestampe = m.maxtimestamp
SQL Fiddle
I'm not sure about MySQL but Oracle supports window functions, so I can write something like:
select first_value(comment) over (order by timestamp desc)
from comments
Here's the easy way to do it with mysql:
SELECT * from (
SELECT match_id, timestampe as maxtimestamp, comment
FROM comments
order by maxtimestamp DESC) x
GROUP BY match_id
This exploits the customised way mysql handles group by.
to not use a subquery, you can use this below query
SELECT match_id,timestampe,comment,
IF(#prevMatchId IS NULL OR #prevMatchId != match_id,#row:=1,#row:=#row+1) as row,
#prevMatchId := match_id
FROM comments
HAVING row = 1
ORDER BY match_id,timestampe DESC
try using EXPLAIN and see which queries are more optimal
here's EXPLAIN on two queries. http://sqlfiddle.com/#!2/70efa/9/1 I am not all that familiar with EXPLAIN so maybe some experts can interpret it.
here's an EXPLAIN on two queries. if i added indexes on match_id and timestampe http://sqlfiddle.com/#!2/30266/1/1

Aggregate functions conflict with some column in my query

I have two tables :
users:
___________________________
|user_id | username |
|_______________|___________|
| 1 | Dolly |
| 2 | Didi |
|_______________|___________|
forum:
_____________________________________________________________
|match_static_id| comment | timpstamp | user_id |
|_______________|___________|______________________|__________|
| 1 | Hi | 2013-07-10 12:15:03 | 2 |
| 1 | Hello | 2013-07-09 12:14:44 | 1 |
|_______________|___________|______________________|__________|
this query is working fine and it uses just thw forum table:
SELECT forum.match_static_id,
count(forum.match_static_id) 'comments_no', max(forum.timestamp)'timestamp'
FROM forum
GROUP BY forum.match_static_id
Order BY timestamp DESC
But the following query is using two tables :
SELECT forum.match_static_id,
count(forum.match_static_id) 'comments_no', max(forum.timestamp)'timestamp', users.username
FROM forum
INNER JOIN users on users.id = forum.user_id
GROUP BY forum.match_static_id
Here I want to get the user of the max(timestamp) but i get the wrong user could any body give my a clue about this, please?
Order BY timestamp DESC
Try this:
SELECT f1.match_static_id,
f2.comments_no,
f2.maxtimestamp,
users.username
FROM forum AS f1
INNER JOIN
(
SELECT match_static_id,
max(timestamp) maxtimestamp,
count(comment) AS comments_no
FROM Forum
GROUP BY match_static_id
) AS f2 ON f1.match_static_id = f2.match_static_id
AND f1.timestamp = f2.maxtimestamp
INNER JOIN users on users.user_id = f1.user_id;
See it in action here:
SQL Fiddle Demo

How to retrieve corresponding value of a filed with MAX on other fields in MySQL 4.0.x

To start with, I am using MySQL 4.0.27 and need solution for this
version only.
I am using MAX() in SELECT statement with other fields and need to retrieve the value of other fields which is corresponding to the value of MAX field.
Assume below data from table Orders:
--------------------------------------------------------------
Product | CategoryID | Date | OrderBy
--------------------------------------------------------------
TV | 1 | 2011-11-27 | John
Pen | 1 | 2011-11-29 | David
Mouse | 2 | 2011-11-30 | Mike
Printer | 1 | 2011-10-19 | Rozi
HDD | 2 | 2011-11-02 | Peter
----------------------------------------------------------------
My requirement is to retrieve count of orders in each category with name of individuals with recent Order, which means I need following result:
--------------------------------------------------------------------------
CategoryID | OrderBy | Order_Count | Date
-------------------------------------------------------------------------
1 | John | 3 | 2011-11-29
2 | Peter | 2 | 2011-11-30
If I use below SQL:
SELECT CategoryID, OrderBy, COUNT(OrderID) AS Order_count, MAX(Date)
FROM Orders
GROUP BY CategoryID
I am not getting desired result. I am getting some other name in OrderBy instead of the same name which is falling against extracted date.
Can anyone suggest how to achieve this in MySQL 4.0.x where we have limitation of not using inner query or functions like GROUP_CONCAT.
Thanks in advance.
Try:
SELECT CategoryID, OrderBy, COUNT(OrderID) AS Order_count, Date
FROM Orders
GROUP BY CategoryID
ORDER BY Date Desc
- assuming you want the OrderBy value corresponding to the maximum date.
Try:
SELECT a.CategoryID, b.OrderBy, COUNT(DISTINCT a.id), MAX(a.Date)
FROM Orders a
INNER JOIN Orders b ON a.CategoryID = b.CategoryID
GROUP BY a.CategoryID
ORDER BY a.Date DESC,b.Date ASC
I always find it a great help to check in the manual (although, despite what it says there, if the value to find the MAX for is not indexed, then this is more efficient than a sub-select)