Mysql sum restult from a query - mysql

I have this table of a database:
cou_id | cou_tea_1 | cou_tea_2 | cou tea_3
1 1 1 2
2 2 1 1
3 4 1 1
Each course has an id, and cou_tea_1, cou_tea_2, cou tes_3 has the teacher that teaches in the lesson 1 of the course, lesson 2 and lesson 3.
In this example in the course 1 the first lesson was made by the teacher 1, the second by the teacher 1 and the third by the teacher 2.
I need a query that gives me the number of the teacher and the total of the lessons he made, in this example:
teacher | total_lesson_number
1 6
2 2
4 1

This is a very poor table design. In general, when you have multiple columns with the same name, you are storing values in columns. These should be in a row.
What you need to do is unpivot the data and then aggregate:
select teacher, count(*) as total_lesson_number
from (select cou_tea_1 as teacher from t union all
select cou_tea_2 from t union all
select cou_tea_3 from t union all
select cou_tea_4 from t
) t
group by teacher;
After getting this to work, you should study up on junction tables so you know the right way to store such data in a relational database.

You can use UNION ALL to unpivot the table, then GROUP BY the teacher id:
SELECT teacher, COUNT(*) AS total_lesson_number
FROM (
SELECT cou_id, cou_tea_1 AS teacher
FROM mytable
UNION ALL
SELECT cou_id, cou_tea_2
FROM mytable
UNION ALL
SELECT cou_id, cou tea_3
FROM mytable) AS t
GROUP BY teacher

Not a new idea I did not want to discard...
select teacher, sum(n) as total_lesson_number from (
(select cou_tea_1 as teacher, count (*) as n from course group by cou_tea_1)
union all
(select cou_tea_2 as teacher, count (*) as n from course group by cou_tea_2)
union all
(select cou_tea_3 as teacher, count (*) as n from course group by cou_tea_3)
)
group by teacher

Related

MySql Select Statement (Other Company)

I am trying to select distinct users that are listed for other companies but not on my company (1). Here is an example
Placement User Company
1 1 1
2 1 2
3 2 2
4 3 1
5 2 1
From this table, I would like to get row 4 since he is in other company (not 1) but listed on others. I do not want others because they are listed on both my company and others. Anyone can help?
You can use NOT IN. For example:
select distinct user
from t
where user not in (
select user from t where company = 1
)
I think that this is the logic that you want:
select t.*
from mytable t
where not exists (
select 1 from mytable t1 where t1.user = t.user and t1.company = 1
)
This gives you the records for which no other record exists for the same user and company 1.

Select most "popular" follower for particular person. The more followers someone has, the more "popular" they are

Find most "popular" follower for a specific person. The more followers someone has, the more
"popular" they are.
I need SQL query to select most popular follower of particular people.
My Table - (followers)
id | person_id | follower_person_id
1 1 2
2 1 3
3 2 1
4 2 4
5 3 1
6 3 2
7 3 4
8 4 3
For example person_id 1 has total 2 follower, person_id 2 has total 2
followers, person_id 3 has total 3 followers and person_id 4 has total
2 followers.
Therefore, person_id 3 is most popular follower for person_id 1,
person_id 1 is most popular follower for person_id 2 and so on...
Here is my query but its not working...
SELECT follower_person_id FROM followers f where f.person_id = 1 group by f.follower_person_id having max(select count(*) from followers where person_id = f.follower_person_id)
You can use the following query to get the number of followers for each person:
SELECT person_id, COUNT(*) AS cnt
FROM followers
GROUP BY person_id
Output:
person_id cnt
-------------
1 2
2 2
3 3
4 1
Using the above query as a derived table you can get the number of followers for follower for each person (sounds a bit complicated!):
SELECT t1.person_id, t1.follower_person_id, t2.cnt
FROM followers AS t1
JOIN (
SELECT person_id, COUNT(*) AS cnt
FROM followers
GROUP BY person_id
) AS t2 ON t1.follower_person_id = t2.person_id
Output:
person_id, follower_person_id, cnt
------------------------------------
1, 2, 2
1, 3, 3
2, 1, 2
2, 4, 1
3, 1, 2
3, 2, 2
3, 4, 1
4, 3, 3
Since you are looking for just a specific person, you can use a WHERE clause in the above query:
SELECT t1.person_id, t1.follower_person_id, t2.cnt
FROM followers AS t1
JOIN (
SELECT person_id, COUNT(*) AS cnt
FROM followers
GROUP BY person_id
) AS t2 ON t1.follower_person_id = t2.person_id
WHERE t1.person_id = 1
ORDER BY t2.cnt DESC LIMIT 1
ORDER BY with LIMIT will give you the most popular person the specific person is following.
Output:
person_id, follower_person_id, cnt
-----------------------------------
1, 3, 3
Note: You can generalize the output of the second query using variables to get the most popular person each person follows (this is a greatest-per-group problem).
could you be looking for something like
SELECT person_id,COUNT(person_id) as followerCount FROM followers
GROUP BY person_id ORDER BY COUNT(person_id) DESC;
This will arbitrarily pick one of the most popular followers if there is a tie for a single person, but it does give the desired result.
SELECT
person_id,
(
SELECT
_f.follower_person_id
FROM
followers _f
WHERE
_f.person_id = f.person_id
GROUP BY
_f.follower_person_id
ORDER BY
COUNT( _f.follower_person_id ) DESC
LIMIT 1
)
FROM
followers f
GROUP BY
person_id
Working SQL Fiddle
You need to do group by person id not by follower id, should take follower_id count .
SELECT person_id ,count(follower_person_id) FROM followers f group by f.person_id
having count(follower_person_id)=(select max(f_cnt ) from
(select count(follower_person_id) f_cnt from followers group by person_id))
If there are 2 persons with same number of most popular then it will return those 2 person with same count
#Parth Can you try this smaller version, i think this is small and simple to understand
With temp as
(
select a.id, a.person_id, count(b.follower_person_id) as follower from
TableName a
inner join TableName b on a.person_id=b.follower_person_id
Group by a.person_id
)
select top 1 * from temp order by follower_person_id desc

Mysql count(*) based in two relations

I would like to count(*) how much customers have created a post or made a comment. If the same customer has made several posts and comments, it should count only once.
Customer Table:
ID Name ...
1 Jonh
2 Mark
3 King
4 Doe
Post Table:
ID USER_ID...
1 1
2 1
3 3
4 1
Comment Table:
ID USER_ID...
1 1
2 3
3 3
4 4
It should return count(*) = 3
(user_id: 1, 3 and 4).
Try this one. It worked for me and returns what you're looking for:
SELECT COUNT( USER_ID ) AS TOTAL
FROM (
SELECT USER_ID
FROM POSTS
UNION
SELECT USER_ID
FROM COMMENTS
)X
I used POSTS and COMMENTS as table names bc I was unsure what your exact table names are, so make sure to change these in your query.
This should work:
SELECT COUNT(DISTINCT USER_ID) FROM (
SELECT USER_ID FROM POST_TABLE
UNION
SELECT USER_ID FROM COMMENT_TABLE
)

MySQL-Count from 2 tables

I have 2 tables. Table table1 like this
specialty doctor
1 A
1 B
2 A
2 C
Table table2 like this:
specialty doctor
1 A
1 D
2 C
I want to count distinct doctor from both the table group by specialty and have the output like this
specialty doctor
1 3
2 2
(specialty 1 has 3 doctors:A, B, D; specialty 2 has 2 doctors: A, C)
Really appreciate your help
You can use union to bring the tables together and then group by:
select specialty, count(*)
from ((select specialty, doctor from table1) union
(select specialty, doctor from table2)
) t
group by specialty;
Note the use of union here and not union all. You specifically want to eliminate duplicates.

How can I select classmates of a given student from a student-class association table?

If my table looks like the following, how can I select classmates of a given student?
student_class_assn
student_id class_id
1 1
2 1
3 1
4 2
5 2
6 3
For example, Student 1 has students 2 and 3 as classmates.
Please help me write a query that pivots on the known student_id and selects only the classmates (and not including the given student).
Here is an example using a sub-select. But can you help me write it with joins instead?
SET #KNOWN_STUDENT=1;
SELECT
student_id
FROM
student_class_assn
WHERE
class_id IN (
SELECT class_id FROM student_class_assn WHERE student_id = #KNOWN_STUDENT
)
AND student_id != #KNOWN_STUDENT;
Given my table above I expect the following results for each given student_id:
1 returns 2,3
2 returns 1,3
3 returns 1,2
4 returns 5
5 returns 4
6 returns NULL
all you need to do is just join the table and pass a conditional
SELECT t1.student_id
FROM student_class_assn t
JOIN student_class_assn t1
ON t1.class_id = t.student_id
AND t1.student_id <> 1
WHERE t.student_id = 1
FIDDLE
This will not show students with no classmates:
select s1.sid,group_concat(s2.sid order by s2.sid,',')
from
stud_class s1 inner join
stud_class s2 on s1.cid=s2.cid
where s1.sid <> s2.sid
group by s1.sid
order by 1