MySQL count records matching distinct column values - mysql

My database includes a column for people's names. Unfortunately, the column includes slight variations of people's name. I would like a query that returns a distinct list of names and the count of records for each variation.
Here is what the column looks like:
+---------------+
| Customer |
+---------------+
| Stan c. Smith |
| Stan c Smith |
| Stan c. Smith |
| Stan c Smith |
| Stan c, Smith |
| Stan c Smith |
+---------------+
I want this result:
Stan c. Smith 2
Stan c Smith 3
Stan c, Smith 1
This is my query:
SELECT
DISTINCT(`Customer`) as aCustomer, COUNT(`Customer`)
FROM
`customerTable`
where
`Customer` like "%Stan%c%Smith%"
But it only returns:
Stan c Smith 6
I have two questions:
Why does MySQL only list one result?
What do I need to do to get the results I am looking for?
Thank you.

To answer your questions:
1) Count is an aggregate function, which returns the total number of rows, by default this will return 1 value unless you use a GROUP BY
2) Use GROUP BY Customer this will group all Customers with the same name together, then running a count should result in a count of each unique instance:
SELECT
`Customer`, COUNT(`Customer`)
FROM
`customerTable`
WHERE
`Customer` like "%Stan%c%Smith%"
GROUP BY `Customer`
See the SQLFiddle for a demo

You should use group by, the below query should give you the result
SELECT
`Customer` as aCustomer, COUNT(`Customer`) as count
FROM
`customerTable`
where
`Customer` like "%Stan%c%Smith%"
group by aCustomer

Related

How can I create a Group_Concat field per table using values from other records

Suppose a table of First and Last Names and for each record I want to do comma-delimited list of relatives.
1ST | LAST | RELATIVES
Bob | Smith | Alice,Andrew
Alice | Smith | Bob,Andrew
Andrew |Smith | Bob,Alice
Alex | Jones | Anny, Ricky
Anny | Jones | Alex, Ricky
Ricky | Jones | Alex, Anny
As per this sqlFiddle
http://sqlfiddle.com/#!9/25d80c/1
I know how to group_contact manually for any last name but am unclear how for each record I could have it go find the records with matching last name and run the same group_concat
You can do it with a self LEFT join and aggregation:
SELECT s1.First, s1.Last,
GROUP_CONCAT(s2.First) Relatives
FROM Surnames s1 LEFT JOIN Surnames s2
ON s2.Last = s1.Last AND s2.First <> s1.First
GROUP BY s1.First, s1.Last;
See the demo.
You can put the aggregation in a lateral join, like so:
select s.First, s.Last, r.Relatives
from Surnames s,
lateral (
select group_concat(First) Relatives
from Surnames r
where s.Last = r.Last AND s.First != r.First
)r
DB<>Fiddle

SQL Query joins tables and returns all records with dynamic id

I have two tables: staffs and teams. Here are their properties:
# Staffs Table
id | name
1 | john
2 | bob
3 | alex
4 | george
# Teams Table
id | name | supervisor_id
1 | a-team 1
2 | b-team 1
3 | c-team 2
4 | d-team 3
I want to write a query that returns all the staff id's records who are supervisors. I know how to join the table but then I don't know how to finish out the query. I also do not want duplicates.
In the above example data: the staff ids for "john", "bob" and "alex" should all be returned once. The staff id for "george" should not be returned because he is not a supervisor.
SELECT distinct(staffs.id)
FROM staffs
INNER JOIN teams
ON staffs.id = teams.supervisor_id
WHERE ??? ;
Would be easier to do with a subquery in the where clause
SELECT distinct(staffs.id)
FROM staffs
WHERE staffs.ID IN (select supervisor_id from Teams)
EDIT:
SQL Fiddle

Select Distinct value Multiple Columns

This is my simplified table
year | teacher
1 | john
2 | john
2 | sam
3 | john
3 | simon
When I run the query below
SELECT year, teacher FROM table1 GROUP BY year
It gives me the result :
year | teacher
1 | john
2 | john
3 | john
In this case, year column is fine as it shows all distinct value, however teacher column is still repeated. I wish to have distinct values on teacher columns too.
Output I am looking for :
year | teacher
1 | john
2 | sam
3 | simon
This query is not valid SQL (even if MySQL happens to accept it):
SELECT year, teacher
FROM table1
GROUP BY year;
You need an aggregation function around teacher:
SELECT year, MAX(teacher)
FROM table1
GROUP BY year;
That said, this doesn't do what you want. That is hard to do in a single query. Instead, use two queries:
SELECT DISTINCT year FROM table1;
SELECT DISTINCT teacher FROM table1;

SQL Using results of query to create another table

(SELECT childinfo.first,childinfo.last,COUNT(clubinfo.club) AS clubs_per_student FROM clubinfo
LEFT JOIN childinfo
ON childinfo.child_id=clubinfo.child_id
GROUP BY concat(studentinfo.first,' ',studentinfo.last)
)
Above is the query that I have written to combine the tables childinfo (containing the columns child_id, first name, and last name) and clubinfo (containing columns child_id and club). The above query would produce a table that is something like this:
first | last | sports_per_child
Sally | Jones | 2
Phil | Jones | 1
Jane | Doe | 1
John | Doe | 1
What I am looking to do is use the results of that query to produce a report of the total number of students who are in a particular number of clubs. So, for example, the table above would produce a report that there are 3 students that are in 1 club and 1 student that is in 2 clubs.
Any ideas on how to write a query that uses my previously written query as a subquery to accomplish this?
You just need to get a count and group by sports_per_child:
SELECT sports_per_child, count(*) FROM
(subquery) AS S
group by sports_per_child

How to format and print a result of sql query

I recently got this question on interview which I failed to answer. The question was to list the number of duplicates that appear in a column employer like from this table
id | employer | employee
1 | isro | dude1
2 | isro | dude 2
3 | cnd | dude 3
4 | df | dsfdef
5 | dfdf | dfdfd
...
so the result should be like
isro = 2
df = 4
dfsf = 6
how do i achieve this?
I know there is count(*) which i could use with select statement with where clause, but how do i achieve the above result.
The HAVING clause can be used to filter on aggregated values:
SELECT employer, COUNT(*)
FROM yourTable
GROUP BY employer
HAVING COUNT(*) > 1
assuming TableName is the name of the table you want to select from, this would be your answer.
SELECT employer, count(employer)
FROM TableName
GROUP BY employer
HAVING COUNT(*) > 1
here is an answer to a very similar question that has some more info for you.
How to count occurrences of a column value efficiently in SQL?