Single MySQL query on three tables - mysql

I have three tables as below:
Table 1: player_game
player_id | game_id
-------------------
1 | 1
2 | 2
5 | 20
4 | 1
2 | 20
-------------------
Table 2: players
player_id | player_name | player_age
------------------------------------
1 | John | 20
2 | Abe | 18
5 | Lisa | 21
4 | Mary | 25
3 | Romeo | 21
------------------------------------
Table 3: games
game_id | game_name | diff_level
------------------------------------
1 | AOE | easy
2 | Contra | easy
11 | Tribalwars | difficult
20 | Tanks | novice
25 | Minesweeper | medium
------------------------------------
I want to write a query that looks up the players and games table by using the IDs on the player_game table. The resulting table should give the player name and the corresponding games name. All the names of the players should be returned. If any player does not have an ID in the player_game table, it should list a NULL. Expected output is below:
Result:
Player Name | Games Name
--------------------------
John | AOE
Abe | Contra
Lisa | Tanks
Mary | AOE
Romeo | NULL
Abe | Tanks
--------------------------
I have written the following query but its not working:
SELECT p.player_name AS "Player Name", g.game_name AS "Games Name"
FROM players p
LEFT OUTER JOIN player_game pg
ON p.player_id = pg.player_id
JOIN games g
ON g.game_id = pg.game_id;
Please advise what am I doing wrong.

Your answer looks good except your 2nd join. Your 2nd join should also be left(outer) join otherwise you won't be seeing "Romeo NULL" record.
Other than this, Abe has 2 games linked( Contra and Tanks) as it is already mentioned. You expect to see both of them in your output? If so, your code will do it. If you want Abe to have only one game linked, then you need to tell us the logic for selecting the one of the games.

Related

How to select a column's value, only if all other entries with the same value exist and match? (MYSQL)

The title is a bit messy, but here's an example
suppose we have table:
| name | room |
=================
| John | 4 |
| John | 6 |
| John | 9 |
| Smith | 4 |
| Smith | 6 |
| Brian | 4 |
| Brian | 6 |
| Brian | 9 |
I want to select John and Brian because they both have exactly rooms 4, 6 and 9, but not Smith, since he doesn't have the room 9. (If we had another person who ONLY has room 4 and 6, then it'd select that other person as well as Smith).
I know I need to do some kind of correlated query, but I'm not sure how to actually get it to do something like
for a check for b
If you want groups of names that share the exact same rooms, I would recommend group_concat():
select rooms, group_concat(name) as names
from (select name, group_concat(room order by room) as rooms
from t
group by name
) n
group by rooms;
If you want only combinations with more than one name, then add having count(*) > 1 to the outer select.

Count multiple items in the same column pulling data from 2 tables - mysql

I have 2 tables and I need to count the number of times any role shows up in each movie
Example of Tables:
Movie Table
TITLE MOVIEID OTHER STUFF....
------------- -------
MOVIE TITLE 1 ID# 1
MOVIE TITLE 2 ID# 2
MOVIE TITLE 3 ID# 3
ETC...
Role Table
ROLEID MOVIEID OTHER STUFF....
------- -------
ROLE #1 ID# 1
ROLE #2 ID# 1
ROLE #3 ID# 2
ROLE #4 ID# 2
ROLE #5 ID# 3
ROLE #6 ID# 4
ROLE #7 ID# 5
ROLE #8 ID# 3
ETC....
I would like to get an output that looks like this:
TITLE NUMROLES
------------- --------------------------------------
MOVIE TITLE 1 COUNT (ROLE.MOVIEID) FOR MOVIE TITLE 1
MOVIE TITLE 2 COUNT (ROLE.MOVIEID) FOR MOVIE TITLE 2
MOVIE TITLE 3 COUNT (ROLE.MOVIEID) FOR MOVIE TITLE 3
MOVIE TITLE 4 COUNT (ROLE.MOVIEID) FOR MOVIE TITLE 4
MOVIE TITLE 5 COUNT (ROLE.MOVIEID) FOR MOVIE TITLE 5
ETC...
I have tried a several different things but I seem to always get a total count of all the roles instead of them being counted individually.
My "best" output Example:
mysql> SELECT TITLE, COUNT(ROLE.MOVIEID) AS NUMROLES
-> FROM MOVIE, ROLE
-> GROUP BY TITLE;
+-----------------------------+----------+
| TITLE | NUMROLES |
+-----------------------------+----------+
| Amadeus | 138 |
| Apollo 13 | 138 |
| Batman | 138 |
| Batman & Robin | 138 |
| Batman Begins | 138 |
| Batman Forever | 138 |
| Batman Returns | 138 |
| Casablanca | 138 |
| Dirty Harry | 138 |
| Few Good Men, A | 138 |
| Field of Dreams | 138 |
| Fly, The | 138 |
| Forrest Gump | 138 |
| Godfather, The | 138 |
| Gone with the Wind | 138 |
| Jerry Maguire | 138 |
| Mrs. Doubtfire | 138 |
| Naked City, The | 138 |
| Sixth Sense, The | 138 |
| Sudden Impact | 138 |
| Terminator 2: Judgment Day | 138 |
| Terminator, The | 138 |
| Tootsie | 138 |
| Wizard of Oz, The | 138 |
+-----------------------------+----------+
24 rows in set (0.02 sec)
I am thinking I don't have the proper knowledge of what I should be using in this case, can anyone point me in the right direction without just giving me the answer??
Bonus:
I also need to filter out any titles that don't have at least 6 for count of (ROLE.MOVIEID) - I am thinking I need to use HAVING for that.
You're really close, just need to tweak your JOIN (it is missing a predicate), and add your HAVING for your bonus:
SELECT TITLE, COUNT(*) AS NUMROLES
FROM MOVIE M
JOIN ROLE R ON M.MOVIEID = R.MOVIEID --This is the join predicate (condition)
GROUP BY TITLE
HAVING COUNT(*) > 5;
This is explicit JOIN syntax. It's best practice to use this as the implicit variant (ie. commas in your FROM clause) is long since depreciated and harder to use anyway.
Note that you can use COUNT(r.movieID) if you want, but COUNT(*) will count the rows in the same fashion.
Your Query:
SELECT TITLE, COUNT(ROLE.MOVIEID) AS NUMROLES
FROM MOVIE, ROLE
GROUP BY TITLE;
Here, you're doing Cross Join between tables MOVIE & ROLE. Which leads you to wrong result.
What you need here is Inner Join of these 2 tables based on the common column MOVIEID.
Following query should work:
SELECT m.TITLE, COUNT(r.MOVIEID) AS NUMROLES
FROM MOVIE m
inner join ROLE r
on m.MOVIEID = r.MOVIEID
GROUP BY m.TITLE
having NUMROLES >=6;
having NUMROLES >=6 is used to filter out TITLE with 5 or less than 5 counts.
You can learn more about JOIN by clicking here.

Join different sizes

I have one table for workers and an other for offices. One worker can be in different offices or in any.
The tables are like:
**Workers**
ID | Name
1 | Ned
2 | James
3 | Tyrion
**WorkersOffices**
WorkerID | OfficeID
1 | 18
1 | 17
2 | 18
I want to join the two tables to get something like this:
**Joined**
ID | Name | OfficeID
1 | Ned | 18
1 | Ned | 17
2 | James | 18
3 | Tyrion |
I have tried the following but it only join one office for worker.
SELECT * FROM workers w
LEFT JOIN workersoffice wo on w.id = wo.workerid
How can I obtain this result?
You have to use LEFT JOIN for that:
SELECT * FROM workers w
LEFT JOIN workers_office wo on w.id = wo.worker_id
Which will basically take all the rows from workers table and join office, if it exists for that worker.
Another thing to mention which is not related to the question is to use a singular name of the tables, you can read more about it in this SO answer
This is what you need:
select w.id,w.name,wo.office_id from workers w left join WorkerOffices wo on w.id = wo.worker_id;
Result set:
+------+--------+-----------+
| id | name | office_id |
+------+--------+-----------+
| 1 | Ned | 18 |
| 1 | Ned | 17 |
| 2 | James | 18 |
| 3 | Tyrion | NULL |
+------+--------+-----------+
#Uri Your query after join just use "group by workers I'd or name".
It will definitely help you in this. And your join is correct. Then you will b egg able to get no of locations of workers.

How to count unique items in column in Access

I need help. I can't seem to find the logic behind this code.
I am working on a voting system, and I need to output the results of the votes.
I want to count all of the rows that has a unique name in it and output how many.
My table goes like this.
voterid | pres | vpres | sec | trea | PIO
---------------------------------------------
1 | John | Mitch | James | Jack | Eman
2 | John | Pao | Bryan | Jack | Faye
3 | Kelvin | Pao | James | Jeck | Faye
Output should be
Pres | Votes
--------------
John | 2
Kelvin | 1
Here's my code.
SELECT DISTINCT
pres,
(SELECT COUNT(pres) FROM (SELECT DISTINCT pres FROM tblVote AS Votes)) AS Votes
FROM tblVote
Thanks in advance!
I think you are just looking for a simple GROUP BY query:
SELECT pres, COUNT(*) AS Votes
FROM tblVote
GROUP BY pres

Getting count byjoining multiple tables

I have 3 tables
1)question
2)options
3)answers
Table 1 contains list of multiple choice questions. Table 2 contains multiple choices for the question.
Consider an example, I have the question "Which game do you like most?"
It is stored in table 1 with id 1. For this question there are 3 choices in table 2; as "cricket", "football", "tennis" with ids 1,2 & 3.
When a user answer this question the question id, and option id are stored to the third table as if he select football, entry in table 3 is question id and option id.
If another user select same option new entry is stored in table 3.
My need is that I want to get the count of each options in table 3.
Consider 10 users select cricket, 15 users select football, no user select tennis, so I need count as 10,15,0 with its corresponding option id
Table name: questions
--------------------------------
| id | question |
--------------------------------
| 1 | which game u like most |
Table Name: options
------------------------------------------------
| id | qid | option_name |
------------------------------------------------
| 1 | 1 | cricket |
------------------------------------------------
| 2 | 1 | football |
------------------------------------------------
| 3 | 1 | tennis |
------------------------------------------------
Table Name: answers
--------------------------------------------
| id | qid | optionId |
--------------------------------------------
| 1 | 1 | 3 |
---------------------------------------------
| 2 | 1 | 3 |
----------------------------------------------
| 3 | 1 | 2 |
----------------------------------------------
The above table means that, 2 people choose tennis, 1 people choose football and no one choose cricket. So I need result table as
------------------------------------------------------
| id | question | option_name | count |
------------------------------------------------------
| 1 | which game u like most | cricket | 0 |
-------------------------------------------------------
| 2 | which game u like most | football | 1 |
-------------------------------------------------------
| 3 | which game u like most | tennis | 2 |
-------------------------------------------------------
But when I tried, I didnt get the count for cricket, because no one selected cricket.I must get count of cricket as 0. Can any one help me solve the issue?
My sql code is
SELECT count(an.optionId) count , op.option_name, q.question from
questions q, options op, answers an where q.id=1
and q.id=op.qid
and op.id=an.optionId
group by q.question, op.option_name
Just use a LEFT JOIN and COALESCE() :
SELECT COALESCE(count(an.optionId),0) as count , op.option_name, q.question from
questions q
INNER JOIN options op
ON(q.id=op.qid )
LEFT OUTER JOIN answers an
ON(p.id=an.optionId)
where q.id=1
group by q.question, op.option_name
Please avoid the use of implicit join syntax(comma separated ) and use only the correct syntax of a join! LEFT JOIN with implicit syntax getting more hard to read and more easy to make mistakjes.