MySQL - count records and list people - mysql

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;

Related

Group together rows with similar date in SQL

In MySQL, I have a query that simplifies a table. Here is the query and the result:
Query:
SELECT
test.`ASSEMBLING-TAG`.`Name 5` AS tag,
DATE(test.`ASSEMBLING-TAG`.datetimetemp) AS date
FROM
test.`ASSEMBLING-TAG`
GROUP BY `Name 5` , datetimetemp
ORDER BY `Name 5`
Result:
From this result, I would like to group the rows by tags with the same date and count them, like so:
Expected output:
| tag | date | count |
|----------------|------------|-------|
| G_GoodPieces_R | 2016-01-01 | 10 |
| G_GoodPieces_R | 2016-01-02 | 1 |
How can I achieve that ?
Then simply group by the date of the datetime.
And count them.
SELECT
t.`Name 5` AS tag,
DATE(t.datetimetemp) AS date,
COUNT(*) AS Total
FROM test.`ASSEMBLING-TAG` t
GROUP BY t.`Name 5`, DATE(t.datetimetemp)
ORDER BY t.`Name 5`

MAX function in MySQL does not return proper key value

I have a table called tbl_user_sal:
| id | user_id | salary | date |
| 1 | 1 | 1000 | 2014-12-01 |
| 2 | 1 | 2000 | 2014-12-02 |
Now I want to get the id of the maximum date. I used the following query:
SELECT MAX(date) AS from_date, id, user_id, salary
FROM tbl_user_sal
WHERE user_id = 1
But it gave me this output:
| id | user_id | salary | from_date |
| 1 | 1 | 2000 | 2014-12-02 |
Which is correct as far as the max date being 2014-12-02, but the corresponding id is not correct. This happens for other records as well. I used order by to check but that was not successful either. Can anyone shed some light on this?
Note: Its not necessary that max date will have max id, according to my needs. Records can have max date but id may be older.
If you only want to retrieve that information for a single user, which you seem to, because of your WHERE clause, just use ORDER BY and LIMIT:
SELECT *
FROM tbl_user_sal
WHERE user_id = 1
ORDER BY date DESC
LIMIT 1
If you want to do that for every user, however, you will have to get a little bit fancier. Something like that should do it:
SELECT t2.id, user_id, date
--find max date for each user_id
FROM (SELECT user_id, MAX(date) AS date
FROM tbl_user_sal
GROUP BY user_id) AS t1
--join ids for each max date/user_id combo
JOIN tbl_user_sal AS t2
USING (user_id, date)
--limit to 1 id for every user_id
GROUP BY
user_id
You are missing group by clause Try this:
select max(awrd_date) as from_date,awrd_id
from tbl_user_sal
where awrd_user_id = 106
group by awrd_id
What I believe you should do here is have a subquery that pulls the max date, and your outer query looks for the row with that date.
It looks like this:
SELECT *
FROM myTable
WHERE date = (SELECT MAX(date) FROM myTable);
Additional things may need to be added if you want to search for a specific user_id, or get the largest date for each user_id, but this gives your expected results for this example here.
Here is the SQL Fiddle.

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)

Sort data before using GROUP BY?

I have read that grouping happens before ordering, is there any way that I can order first before grouping without having to wrap my whole query around another query just to do this?
Let's say I have this data:
id | user_id | date_recorded
1 | 1 | 2011-11-07
2 | 1 | 2011-11-05
3 | 1 | 2011-11-06
4 | 2 | 2011-11-03
5 | 2 | 2011-11-06
Normally, I'd have to do this query in order to get what I want:
SELECT
*
FROM (
SELECT * FROM table ORDER BY date_recorded DESC
) t1
GROUP BY t1.user_id
But I'm wondering if there's a better solution.
Your question is somewhat unclear but I have a suspicion what you really want is not any GROUP aggregates at all, but rather ordering by date first, then user ID:
SELECT
id,
user_id,
date_recorded
FROM tbl
ORDER BY date_recorded DESC, user_id ASC
Here would be the result. Note reordering by date_recorded from your original example
id | user_id | date_recorded
1 | 1 | 2011-11-07
3 | 1 | 2011-11-06
2 | 1 | 2011-11-05
5 | 2 | 2011-11-06
4 | 2 | 2011-11-03
Update
To retrieve the full latest record per user_id, a JOIN is needed. The subquery (mx) locates the latest date_recorded per user_id, and that result is joined to the full table to retrieve the remaining columns.
SELECT
mx.user_id,
mx.maxdate,
t.id
FROM (
SELECT
user_id,
MAX(date_recorded) AS maxdate
FROM tbl
GROUP BY user_id
) mx JOIN tbl t ON mx.user_id = t.user_id AND mx.date_recorded = t.date_recorded
Iam just using the technique
"Using order clause before group by inserting it in group_concat clause"
SELECT SUBSTRING_INDEX(group_concat(cast(id as char)
ORDER BY date_recorded desc),',',1),
user_id,
SUBSTRING_INDEX(group_concat(cast(`date_recorded` as char)
ORDER BY `date_recorded` desc),',',1)
FROM data
GROUP BY user_id

MySQL: How to GROUP BY a field to retrieve the rows with ORDER BY another field?

assume following data:
Data:
id | date | name | grade
--------+---------------+-----------+---------------
1 | 2010/12/03 | Mike | 12
2 | 2010/12/04 | Jenny | 12
3 | 2010/12/04 | Ronald | 15
4 | 2010/12/03 | Yeni | 11
i want to know who has the best grade in each day, something like this:
Desired Result:
id | date | name | grade
--------+---------------+-----------+---------------
1 | 2010/12/03 | Mike | 12
3 | 2010/12/04 | Ronald | 15
i thought query should look like this:
SELECT name FROM mytable
GROUP BY date
ORDER BY grade DESC
but it returns something like this:
Current Unwanted Result:
id | date | name | grade
--------+---------------+-----------+---------------
1 | 2010/12/03 | Mike | 12
2 | 2010/12/04 | Jenny | 12
i searched and i found the reason:
GROUP BY happens before ORDER BY so it does not see and can't apply ORDER.
so how can i apply ORDER on GROUP BY?
Note: please keep in mind that i need the most simple query, because my query is actually very complex, i know i can achieve this result by some subquery or JOINing, but i want to know how to apply ORDER to GROUP BY. thanks
I used Oracle for this example, but the SQL should work in mysql (you may need to tweak the to_date stuff to work with mysql). You really need a subquery here to do what you are asking.
CREATE TABLE mytable (ID NUMBER, dt DATE, NAME VARCHAR2(25), grade NUMBER);
INSERT INTO mytable VALUES(1,to_date('2010-12-03','YYYY-MM-DD'),'Mike',12);
INSERT INTO mytable VALUES(1,to_date('2010-12-04','YYYY-MM-DD'),'Jenny',12);
INSERT INTO mytable VALUES(1,to_date('2010-12-04','YYYY-MM-DD'),'Ronald',15);
INSERT INTO mytable VALUES(1,to_date('2010-12-03','YYYY-MM-DD'),'Yeni',11);
SELECT id
, dt
, name
, grade
FROM mytable t1
WHERE grade = (SELECT max(grade)
FROM mytable t2
WHERE t1.dt = t2.dt)
ORDER BY dt
Results:
ID DT NAME GRADE
1 12/3/2010 Mike 12
2 12/4/2010 Ronald 15
I know you said you wanted a GROUP / ORDER only solution but you will need to use a subquery in this instance. The simplest way would be something like this:
SELECT id, date, name, grade
FROM mytable t1
WHERE grade =
(SELECT MAX(t2.grade) FROM mytable t2 WHERE t1.id = t2.id)
This would show multiple students if they shared the highest grade for the day.