MySQL SUM by field an then GROUP BY user? - mysql

I have this table:
What's the correct query to get this result:
ID | Type | Total
1 | A | 300
1 | B | 100
2 | A | 30
2 | B | 40
Which means sum by type first and then group by user id?

Your aggregate functions, such as SUM, are performed on your groups; so there is no "SUM by type first then group by user_id", you are wanting to group by user_id and type.
Like so: GROUP BY user_id, type
If you want to guarantee that ordering in the future also have an ORDER BY user_id, type clause as well. Currently, GROUP BY also orders, but I believe that feature has been marked as deprecated recently.

Related

Get top N rows of each group in MySQL

Given a MySQL table of the form
Name | Type
-------+-----
Bill | A
Hill | B
Jill | C
Hans | A
George | C
Sophie | B
Hannah | B
Nancy | C
Phil | A
... | ...
I would like to produce a MySQL query which provides me with the top N rows grouped by their type. By 'top' I mean with respect to a given ordering. In this example, it could be the order given by ordering the type parameters alphabetically (or by date, if all type parameters are dates). For instance, if N = 2, then the resulting table could be:
Name | Type
-------+-----
Bill | A
Hill | B
Jill | C
Hans | A
George | C
Sophie | B
... | ...
That is, the entries may very well be grouped into their respective types in the resulting tables, but it is not strictly important that they are. I run MySQL 8.x.
If you want n rows per group, use row_number(). If you then want them interleaved, use order by:
select t.*
from (select t.*,
row_number() over (partition by type order by name) as seqnum
from t
) t
where seqnum <= 2
order by seqnum, type;
This assumes that "top" is alphabetically by name. If you have another definition, use that for the order by for row_number().

Limit MySQL Results to One From Each "Group"

Suppose we have a table like the one below.
Id | Name | Group
-----------------
1 | John | 1
2 | Zayn | 2
3 | Four | 2
4 | Ben_ | 3
5 | Joe_ | 2
6 | Anna | 1
The query below will select all of them.
SELECT `Name` FROM `Table` WHERE 1;
How would I select only one person from each group? Who it is doesn't really matter, as long as there's only one name from group 1 and one name from group 2 etc.
The GROUP BY clause isn't fit for this (according to my error console) because I am selecting non aggregated values, which makes sense.
The DISTINCT clause isn't great here either, since I don't want to select the "Group" and definitely not group by their names.
If is not important the resulting name You can anawy leverage some group functions eg with max or min..
leverage the group functions
select max(name) from your_table
group by Group;
otherwise you can use subquery
select name from your_table
where Id in (select min(Id) from your_table group by Group);

Query to Find Duplicate entries

I am looking for an SQL query to give me a list of duplicate entries in a table. However, there are 3 different columns to take into account. First is an ID, Second is a Name, and third is a Date. The situation is that there are multiple Names that are assigned with the same ID, and there are multiple records of those in a day, which makes THOUSANDS of different records per day.
I already filtered it so that only results for the past 7 days will show, but the amount of records is still too much for me to extract. I just want to decrease the number of rows in the output order to properly extract the results.
Sample
|--id-|--name--|-------date------|
| 1 | a |5-9-2015, 10:00am|
| 1 | a |5-8-2015, 10:02am|
| 1 | a |5-8-2015, 11:00am|
| 1 | b |5-8-2015, 10:00am|
| 1 | b |5-8-2015, 10:02am|
| 1 | c |5-8-2015, 10:00am|
| 2 | d |5-8-2015, 10:00am|
expected output
|--id-|--name--|
| 1 | a |
| 1 | b |
| 1 | c |
| 2 | d |
Inclusion of entries without any duplicates are fine. The important thing is to only return a single record of a unique id-name combination for a day.
Thanks in advance for any help that you can give.
You can get the combinations as:
select distinct id, name
from sample;
If you want duplicates, using group by and having:
select id, name
from sample
group by id, name
having count(*) > 1;
EDIT:
If you want this by date, then add date(date) to the group by and perhaps select clauses.
To return single id-name data per day you can use this:
select id, name
from tab
group by id, name, date(date)
The DATE() function extracts the date part of a date or date/time expression.
select id,name
from sample
group by id,name,DATE(date)
having count(*)>1;

Get one record per unique column value

I have a table that list system licences, multiple licences for each system (the expired ones and existing ones). I've only posted two columns in this question as they're the only important ones.
| id | systemid |
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
| 5 | 3 |
| 6 | 3 |
I need to get the rows with the id of 2, 4 and 6.
I need to collect 1 record for each systemid and it has to be the earliest (youngest) record, so in this case, the record with the highest id. I've been exploring GROUP BY, ORDER BY and LIMIT but I'm not producing the result I'm after. How do you collect one record for each individual value in one column and make sure it's the record with the highest id?
I KNOW this is wrong, but it's what I'm currently starring at:
SELECT * FROM licences GROUP BY systemid ORDER BY id DESC LIMIT 1
SELECT max(id), systemid FROM table GROUP BY systemid
Note that with a GROUP BY, all columns you select must either be in the GROUP BY clause or wrapped in an aggregating function, like max, min, sum, or average.
This will grab the highest id per systemid.
SELECT MAX(id), systemid
FROM ...
GROUP BY systemid

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)