Count rows grouped by a column when another column is the same - sql

In the following table I would like to count the number of people that submitted at least one solution to a problem.
This is the table:
id user_name problem_name
1 john sums
2 john trees
3 john sums
4 martin sums
5 martin trees
6 martin trees
7 jim trees
This is the result I'm looking for:
sums 2
trees 3
I would group by problem_name, but only when the user_name column is the same. I have no idea how to write this in SQL.

Use count(distinct):
select problem_name, count(distinct user_name) as count
from mytable
group by problem_name

select table_2.problem_name, count(*) from
(select user_name, problem_name
from table_1
group by user_name, problem_name) as table_2
group by problem_name
I think using a subquery is faster than use distinct if you have many rows, but I'm not sure.

Related

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 for 2 columns in SQL query

If I have a table such as
1 bob
1 ray
1 bob
1 ray
2 joe
2 joe
And I want to select distinct based on the two columns so that I would get
1 bob
1 ray
2 joe
How can I word my query? Is the only way to concatenate the columns and wrap them around a distinct function operator?
select distinct id, name from [table]
or
select id, name from [table] group by id, name
You can just do:
select distinct col1, col2 from your_table;
That's exactly what the distinct operator is for: removing duplicate result rows.
Keep in mind that distinct is usually a pretty expensive operation, since, after processing the query, the DB server might perform a sort operation in order to remove the duplicates.

Select top distinct results ordered by frequency

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

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