Select top distinct results ordered by frequency - sql

My table has two columns: id and name. The data looks like this:
id | name
----------
1 Jeff
2 Sam
3 Carl
4 Sam
5 Carl
6 Jeff
7 Dave
8 Jeff
What I want to obtain is this:
name | frequency
----------------
Jeff 3
Carl 2
Sam 2
Dave 1
Essentially, I need an SQL query that counts the unique names within the table, and sorts them by their frequnecy. I'm using MySQL if it matters.
Thank-you.

I haven't tested it, so the syntax might not be perfect, but what about something like this :
select name, count(*) as frequency
from your_table
group by name
order by count(*) desc
Should give you unique names and the corresponding number of times each name appears in the table, ordered by that number.

You need to use a GROUP BY:
SELECT name, COUNT(*) as frequency
FROM name_table
GROUP BY name
ORDER BY COUNT(*) DESC;
This will GROUP BY name (any non-aggregate columns needs to be named in the GROUP BY clause) and then COUNT the frequency of each name.
If you want only the top 25, you can then proceed to add a LIMIT clause as such:
SELECT name, COUNT(*) as frequency
FROM name_table
GROUP BY name
ORDER BY COUNT(*) DESC
LIMIT 25;
More information about the GROUP BY clause is available in the MySQL Manual:
12.2.8 SELECT Syntax

Related

How to get grouping of rows in SQL

I have a table like this:
id name
1 washing
1 cooking
1 cleaning
2 washing
2 cooking
3 cleaning
and I would like to have a following grouping
id name count
1 washing,cooking,cleaning 3
2 washing,cooking 2
3 cleaning 1
I have tried to group by ID but can only show count after grouping by
SELECT id,
COUNT(name)
FROM WORK
GROUP BY id
But this will only give the count and not the actual combination of names.
I am new to SQL. I know it has to be relational but there must be some way.
Thanks in advance!
in postgresql you can use array_agg
SELECT id, array_agg(name), COUNT(*)
FROM WORK
GROUP BY id
in mysql you can use group_concat
SELECT id, group_concate(name), COUNT(*)
FROM WORK
GROUP BY id
or for redshift
SELECT id, listagg(name), COUNT(*)
FROM WORK
GROUP BY id

SQL Separating Distinct Values using single column

Does anyone happen to know a way of basically taking the 'Distinct' command but only using it on a single column. For lack of example, something similar to this:
Select (Distinct ID), Name, Term from Table
So it would get rid of row with duplicate ID's but still use the other column information. I would use distinct on the full query but the rows are all different due to certain columns data set. And I would need to output only the top most term between the two duplicates:
ID Name Term
1 Suzy A
1 Suzy B
2 John A
2 John B
3 Pete A
4 Carl A
5 Sally B
Any suggestions would be helpful.
select t.Id, t.Name, t.Term
from (select distinct ID from Table order by id, term) t
You can use row number for this
Select ID, Name, Term from(
Select ID, Name, Term, ROW_NUMBER ( )
OVER ( PARTITION BY ID order by Name) as rn from Table
Where rn = 1)
as tbl
Order by determines the order from which the first row will be picked.

IN SQL count after group by

i want to count after group by, not the total line
just want to count by the categories
after group by my result is like
course lecturer
comp1111 Jim
comp1100 Jim
comp1100 Jim
infs2321 Jess
infs2321 Jess
econ1222 Helen
my result after count should be
lecturer count
Jim 3
Jess 2
Helen 1
I don't see why you want a group by after you have grouped. You get your desired result by doing just one group. Please have a look at this sqlfiddle to see it working live.
CREATE TABLE Table1
(`course` varchar(8), `lecturer` varchar(5))
;
INSERT INTO Table1
(`course`, `lecturer`)
VALUES
('comp1111', 'Jim'),
('comp1100', 'Jim'),
('comp1100', 'Jim'),
('infs2321', 'Jess'),
('infs2321', 'Jess'),
('econ1222', 'Helen')
;
select
lecturer, count(*)
from
Table1
group by lecturer desc;
| LECTURER | COUNT(*) |
-----------|----------|--
| Jim | 3 |
| Jess | 2 |
| Helen | 1 |
EDIT:
You don't need an extra table. To get the row with the largest count you can simply do
select
lecturer, count(*)
from
Table1
group by lecturer
order by count(*) desc
limit 1;
for MySQL or
select top 1
lecturer, count(*)
from
Table1
group by lecturer
order by count(*) desc;
for MS SQL Server. In my first answer I had GROUP BY lecturer DESC which is the same as GROUP BY lecturer ORDER BY COUNT(*) DESC because in MySQL GROUP BY implies an ORDER BY.
If this is not what you want, be careful with using MAX() function. When you simply do for example
select
lecturer, max(whatever)
from
Table1
group by lecturer;
you don't necessarily get the row with holding the max of whatever.
You can also do
select
lecturer, max(whatever), min(whatever)
from
Table1
group by lecturer;
See? You just get the value returned by the function, not the row belonging to it. For examples how to solve this, please refer to this manual entry.
I hope I didn't confuse you now, this is probably more than you wanted to know, because above is especially for groups. I think what you really want to do is simply ordering the table the way you want, then pick just one row, like mentioned above.
Try this. It might work
SELECT LECTURER, COUNT(*)
FROM
(SELECT LECTURER, COURSE
FROM TABLE
WHERE
GROUP BY LECTURER, COURSE )
GROUP BY LECTURER;
try to this command in mysql
============================
select
lecturer, count(*)
from
Course_detail
group by lecturer desc;

Select distinct name with random id

I have a table with an id and a name (an a bunch of other stuff not relevant for this query). Now I need an SQL statement that returns one row per distinct name and in that row I need the name and one id (can be any id).
The table is looking something like this:
id | name
---+-----
1 | a2
2 | a2
3 | a4
4 | a4
5 | a2
6 | a3
btw. using Postgres 8.4
Tried various combinations of grouping or joining with self. Is this even possible without creating extra tables?
Arbitrarily choosing to return the minimum id per name.
SELECT name, MIN(id)
FROM YourTable
GROUP BY name
You may look at PostgreSQL wiki. It shows how to select random rows.
You may use random() function to select random rows using ORDER BY clause of SELECT. Example:
SELECT id FROM mytable ORDER BY random()
You can then use GROUP BY to select distinct names. You may need to limit results using LIMIT clause. So the query looks something like this:
SELECT id, name FROM table_name GROUP BY name ORDER BY random() LIMIT 1
select ID, name from table group by name;

SQL - WHERE AGGREGATE>1

Imagine I have a db table of Customers containing {id,username,firstname,lastname}
If I want to find how many instances there are of different firstnames I can do:
select firstname,count(*) from Customers group by 2 order by 1;
username | count(*)
===================
bob | 1
jeff | 2
adam | 5
How do I write the same query to only return firstnames that occur more than once? i.e. in the above example only return the rows for jeff and adam.
You want the having clause, like so:
select
firstname,
count(*)
from Customers
group by firstname
having count(*) > 1
order by 1
group by 2 order by 1 is terrible, I should say. Use proper column names if that's supported: this will drastically improve readability.
With that in mind,
select firstname, count(*) c
from Customers
group by firstname
having count(*) > 1 -- Kudos to Shannon
order by c;
That's what the HAVING clause does. I'm not sure if this will work in informix, but give it a shot:
select firstname, count(*)
from Customers
group by firstname
HAVING COUNT(*) > 1