MYSQL print names by id with highest occurences in a different table - mysql

I need to write a query listing the name of the staff member(s) who supervise(s) the
highest number of students. The result should also display the number of students.
The query should also work in situations when more than one supervisor has
highest students (e.g. 2 supervisors each having 10 students, 10 being highest).
Every post on stackoverflow I have read about getting the most common value all talk about just listing values by frequency of occurence and then using LIMIT to only show the top one. However I need to do it in such a way that it will show the highest one and any others that are equal to it and it has to be dynamic for a result list of any length.
There is 2 separate tables as below so I figured the query would be something like
Students table
+------------------+----------+
| S_FIRST | F_ID |
+------------------+----------+
| Tammy | 1 |
| jorge | 1 |
| john | 1 |
| mike | 2 |
| lisa | 4 |
| ni | 3 |
faculty table
+------------------+----------+
| F_FIRST | F_ID |
+------------------+----------+
| Teresa | 1 |
| mark | 2 |
| colin | 3 |
| jonnel | 4 |
| james | 5 |
SELECT F_FIRST, COUNT(student.F_ID) AS value_occurrence
from faculty, student
group by F_FIRST
ORDER BY value_occurrence DESC;
But that just gives the below output.
F_FIRST VALUE_OCCURRENCE
--------------- ----------------
Jonnel 6
Mark 6
James 6
Colin 6
Teresa 6
The expected output is
F_FIRST VALUE_OCCURRENCE
--------------- ----------------
Teresa 3

Related

How to join 1 table to another table and get count result per date

I have 3 tables with corresponding fields.
Table 1 (List of Machines)
Machine_No | Machine_Description
1 | Hitachi
2 | Jet Printer
3 | Sumi
Table 2 (List of Manpower)
ID_Number | Employee_Name | Machine_No
1 | Taylor | 3
2 | James | 2
3 | David | 1
Table 3 (Actual Manpower use per machine)
Machine_No | Employee_Number | Date Posted
1 | 1 | 15-10-2019
1 | 2 | 15-10-2019
1 | 3 | 15-10-2019
Now... I want the results to go like this.
Machine_Now | Count(Employee Number) | Date_Posted
1 | 3 | 15-10-2019
Try this, it may work, if I understand your question correctly.
select Machine_No,Date_Posted,count(*) from Table3 group by Machine_No,Date_Posted;

Update with results of Ordered Select into Column

I have a simple table with four columns: id | name | score | rank that looks like this:
id | name | score | rank
---|------|-------|-----
1 | Bob | 99 | -
2 | Jim | 88 | -
3 | Rex | 103 | -
4 | Zus | 55 | -
I'd like to sort these rows by score (descending) and store the approriate ranking in the rank column for each row.
Currently, I'm using the following code to create an alias column that has the rankings:
SET #rank:=0;
SELECT *, #rank:=#rank+1 AS rank_test FROM test ORDER BY score DESC
Which returns:
id | name | score | rank | rank_test
---|------|-------|------|----------
3 | Rex | 103 | - | 1
1 | Bob | 99 | - | 2
2 | Jim | 88 | - | 3
4 | Zus | 55 | - | 4
How can I transfer the result of the rank_test alias into the rank column?
I've researched a lot of answers but can't seem to get anything to work. Fairly new to SQL so I apologize if it's a simple solution. Thank you!

MS Access - display repeating rows once with the highest value

I have 2 tables in MS Access with the following values
Customer
id | name
1 | jon
2 | bob
3 | jack
Order
id | amount | date | customer
5 | 50 | 3/10/2017 | 1
4 | 100 | 3/10/2017 | 1
3 | 45 | 2/28/2017 | 2
2 | 10 | 3/10/2017 | 3
1 | 5 | 3/10/2017 | 2
I want to get an output of
name | orderid | amount
jon | 5 | 50
bob | 3 | 45
jack | 2 | 10
I want to get amount of the latest order id per customer, however I keep getting this
name | orderid | amount
jon | 5 | 50
jon | 4 | 100
bob | 3 | 45
bob | 2 | 10
jack | 1 | 5
I used the query designer and have used the function MAX() to the order id, GROUP BY to all columns (MS Access does not allow to group the rows using a single column), DISTINCT and DISTINCTROW, as well as set the query properties "Unique Records" to Yes but the duplicate records still shows.

Adding sum from 2 different tables

I have something like this
2 tables:
videos
members
In the members table I have the name of each member:
1 Tom
2 Bob
3 Zack
4 Dan
5 Casey
In the videos table I have a column named members and I have the names in there seperated by commas
1. Tom,Dan
2. Casey,Zack,Bob
3. Tom,Casey,Dan,Zack
4. Zack,Bob,Dan
I'm trying to display how many times each member appears to get these results:
1 Tom = 2
2 Bob = 2
3 Zack = 3
4 Dan = 2
5 Casey = 2
Do I need to do something like SELECT SUM(members) WHERE and use LIKE?
I would strongly suggest to normalize your data as others suggested.
Based on your current design you can use FIND_IN_SET to accomplish the result you want.
SELECT
M.id,
M.name,
COUNT(*) total
FROM members M
INNER JOIN videos V ON FIND_IN_SET(M.name,V.members) > 0
GROUP BY M.name
ORDER BY M.id
See Demo
Running this query on your given data set you will get output like below:
| id | name | total |
|----|-------|-------|
| 1 | Tom | 2 |
| 2 | Bob | 2 |
| 3 | Zack | 3 |
| 4 | Dan | 3 |
| 5 | Casey | 2 |
A must read
Is storing a delimited list in a database column really that bad?
More
This is how your vidoes table would look like if you normalize your data:
videos
id member_id
One way to go is to join the two tables, based on a like expression:
SELECT members.name, count (*) as counter from members inner join videos
ON videos.members like CONCAT('%,',members.name,',%')
GROUP BY members.name;
But I think the better solution will be like #e4c5 said in the comment - you need to normalize the data. the videos table should look like:
+---+-------+
|ID | MEMBER|
+---+-------+
| 1 | Tom |
| 1 | Dan |
| 2 | Casey |
| 2 | Zack |
| 2 | Bob |
| 3 | Tom |
| 3 | Casey |
| 3 | Dan |
| 3 | Zack |
| 4 | Zack |
| 4 | Bob |
| 4 | Dan |
+---+-------+
That way, you can simply count on this table

MySql search ranking with criteria

I have table named customers that keeps the customer's data
id | fname | lname
--- | ------ | ------
1 | John | Smith
2 | Mike | Bolton
3 | Liz | John
4 | Mark | Jobs
And i have another table named calls that keeps each call made to each customer.
id | timestamp | customer_id | campaign | answered |
1 |2016-09-05 15:24:08| 1 | 2016-09 | 1 |
2 |2016-09-05 15:20:08| 2 | 2016-09 | 1 |
3 |2016-08-05 15:20:08| 2 | 2016-08 | 1 |
4 |2016-08-05 13:20:08| 3 | 2016-08 | 1 |
5 |2016-08-01 15:20:08| 3 | 2016-08 | 0 |
5 |2016-08-01 12:20:08| 4 | General | 1 |
Campaign General Doesn't count towards the calculations.
I need to get a list of customers ordered by ranking of calling quality based on each customer calling history.
This list is use to call the customers in order that:
Hasn't been called on the actual calling campaign (ex.2016-09)
Has fewer calls
Best % answered (total calls answered / total calls made)
It should look something like this:
| id | fname | lname | %ans | called actual campaign | total calls | rank |
|----|--------|-------|------|------------------------|-------------|------|
| 4 | Mark | Jobs | N/A | no | 0 | 1 |
| 3 | Liz | John | 50 | no | 2 | 2 |
| 1 | John | Smith | 100 | yes | 1 | 3 | No Show
| 2 | Mike | Bolton| 100 | yes | 2 | 4 | No Show
Please help me!
The query which counts for each customer total calls and answered calls for the specified campaign
select
c.id,
count(*) as total_calls,
sum(case when answered=1 then 1 else 0 end) as answered_calls
from customer c
join calls cs on c.id=cs.customer_id
where cs.campaign='2016-09'
group by c.id
Then you can use the query above as a subquery to order
select sub.id, (#rank:=#rank+1) as rank
from (the subquery above) sub, (select #rank:=1)
order by
case when sub.total_calls=0 then 0 else 1,
sub.total_calls,
sub.answered_calls*100/sub.total_calls
You can include any desired columns in the result query