MySQL joining 3 tables using UNION - mysql

This question is a little long so that it would be clear, thanks in advance!
Introduction
I currently have 3 tables using a many-to-many relationship. I need to query all 3 tables and combine them into 1 table.
Problem
I have tried this query:
SELECT * FROM `login` LEFT JOIN membership ON login.id = membership.login_id UNION SELECT * FROM `login` RIGHT JOIN membership ON login.id = membership.login_id
And it returns:
+----+------+----------+
| id | name | group_id |
+----+------+----------+
| 1 | Tom | 6 |
| 2 | John | 8 |
| 3 | Jane | 4 |
+----+------+----------+
Question
I need it to also include the group_name. This is my desired output:
+----+------+----------+------------+
| id | name | group_id | group_name |
+----+------+----------+------------+
| 1 | Tom | 6 | Red |
| 2 | John | 8 | Brown |
| 3 | Jane | 4 | Purple |
+----+------+----------+------------+
Tables
login Table
A list of all users with auto-increment id
+----+------+
| id | name |
+----+------+
| 1 | Tom |
| 2 | John |
| 3 | Jane |
+----+------+
group Table
A list of all groups with the group_id and group_name
+----------+------------+
| group_id | group_name |
+----------+------------+
| 1 | Green |
| 2 | Blue |
| 3 | Yellow |
| 4 | Purple |
| 5 | Orange |
| 6 | Red |
| 7 | Pink |
| 8 | Brown |
+----------+------------+
membership Table
Stores information on which user belongs to which group
+----------+----------+
| login_id | group_id |
+----------+----------+
| 1 | 6 |
| 2 | 8 |
| 3 | 4 |
+----------+----------+

Join the group table as well and select the required fields from the tables.
SELECT l.id,l.name,m.group_id,g.group_name
FROM `login` l
LEFT JOIN `membership` m ON l.id = m.login_id
LEFT JOIN `group` g on g.group_id = m.group_id

Try this... :)
SELECT
`login`.`id`,
`login`.`name`,
`group`.`group_id`,
`group`.`group_name`
FROM
`membership`
INNER JOIN `login` ON (`membership`.`login_id` = `login`.`id`)
INNER JOIN `group` ON (`membership`.`group_id` = `group`.`group_id`)

Related

mySQL SELECT query from multiple tables

I need a help with mySQL SELECT query from multiple tables. I have got four tables: school, discipline, pupils and teams.
School table looks like:
+------+---------+---------------+----------+
| id | name | discipline_id | pupil_id |
+------+---------+---------------+----------+
| 1 | one | 2 | 5 |
+------+---------+---------------+----------+
| 2 | two | 3 | 8 |
+------+---------+---------------+----------+
| 3 | three | 4 | 12 |
+------+---------+---------------+----------+
Discipline table looks like:
+------+---------+
| id | name |
+------+---------+
| 1 | math |
+------+---------+
| 2 | bio |
+------+---------+
| 3 | liter |
+------+---------+
| 4 | geo |
+------+---------+
Teams table looks like:
+------+---------+---------------+-----------+
| id | name | school_id | member_id |
+------+---------+---------------+-----------+
| 1 | T1 | 1 | 3 |
+------+---------+---------------+-----------+
| 2 | T2 | 3 | 3 |
+------+---------+---------------+-----------+
| 3 | T3 | 2 | 9 |
+------+---------+---------------+-----------+
The result of disciplines I need to get with a "SELECT from discipline..." query by "member_id = 3" is:
+-----------------+---------------+
| discipline_name | discipline_id |
+-----------------+---------------+
| bio | 2 |
+-----------------+---------------+
| geo | 4 |
+-----------------+---------------+
By matching member's school and then getting its discipline, if it makes sense...Is it possible to do with just one mySQL query?
Type of: member_id 3 => school_id 1,3 => discipline_id = show related disciplines names and ids which are 2, 4
Thank you very much...
Your goal is not clear or makes no sense to me.
But here is what you are literally asking for:
SELECT
s.discipline_id
d.name
FROM teams t
LEFT JOIN school s
ON s.id = t.school_id
LEFT JOIN discipline d
ON d.id = s.discipline_id
WHERE t.member_id = 3

How can I determine which user is the top one in the specific tag?

I have a question and answer website like stackoverflow. Here is the structure of some tables:
-- {superfluous} means some other columns which are not related to this question
// q&a
+----+-----------------+--------------------------+------+-----------+-----------+
| id | title | body | type | related | author_id |
+----+-----------------+--------------------------+------+-----------+-----------+
| 1 | How can I ... | I'm trying to make ... | q | NULL | 3 |
| 2 | | You can do that by ... | a | 1 | 1 |
| 3 | Why should I .. | I'm wonder, why ... | q | NULL | 1 |
| 4 | | First of all you ... | a | 1 | 2 |
| 5 | | Because that thing ... | a | 3 | 2 |
+----+-----------------+--------------------------+------+-----------+-----------+
// users
+----+--------+-----------------+
| id | name | {superfluous} |
+----+--------+-----------------+
| 1 | Jack | |
| 2 | Peter | |
| 3 | John | |
+----+--------+-----------------+
// votes
+----+----------+-----------+-------+-----------------+
| id | user_id | post_id | value | {superfluous} |
+----+----------+-----------+-------+-----------------+
| 1 | 3 | 4 | 1 | |
| 2 | 1 | 1 | -1 | |
| 3 | 2 | 1 | 1 | |
| 4 | 3 | 2 | -1 | |
| 5 | 1 | 4 | 1 | |
| 6 | 3 | 5 | -1 | |
+----+--------+-------------+-------+-----------------+
// tags
+----+------------+-----------------+
| id | name | {superfluous} |
+----+------------+-----------------+
| 1 | PHP | |
| 2 | SQL | |
| 3 | MySQL | |
| 4 | HTML | |
| 5 | CSS | |
| 6 | C# | |
+----+------------+-----------------+
// q&aTag
+-------+--------+
| q&aid | tag_id |
+-------+--------+
| 1 | 1 |
| 1 | 4 |
| 3 | 5 |
| 3 | 4 |
| 4 | 6 |
+-------+--------+
Now I need to find top users in a specific tag. For example, I need to find Peter as top user in PHP tag. Because his answer for question1 (which has PHP tag) has earned 2 upvotes. Is doing that possible?
Try this:
select q1.title, u.id, u.name, sum(v.value) total from `q&a` q1
left join `q&atag` qt ON q1.id = qt.`q&aid`
inner join tags t ON qt.tag_id = t.id
left join `q&a` q2 ON q2.related = q1.id
left join users u ON q2.author_id = u.id
left join votes v ON v.post_id = q2.id
where t.name = 'PHP'
group by q1.id, u.id
and here is a simple divided solution:
Let us divide it into sub queries:
get the id of the tag you will search for: select id from tags where name = 'PHP'
get the questions with this tag: select 'q&aid' from 'q&aTag' where tag_id = 1.
get the ids of answers for that question: select id, author_id fromq&awhere related in (2.)
get the final query: select user_id, sum(value) from votes where post_id in (3.) group by user_id
Now combining them all give the result:
select user_id, sum(`value`) total from votes
where post_id in (
select id from `q&a` where related in (
select `q&aid` from `q&aTag` where tag_id IN (
select id from tags where name = 'PHP'
)
)
)
group by user_id
you can add this at the end if you want only one record:
order by total desc limit 1

JOIN for a table 2 times

In my MySQL database, I have tables: group, profile and profile_titles.
Here is the structure of table group:
+----------+----------------+------------+
| group_id | title | profile_id |
| 1 | Group Title 1 | 1 |
| 2 | Group Title 2 | 1 |
| 3 | Group Title 3 | 2 |
| 4 | Group Title 4 | 2 |
| ... | Group Title 1 | ... |
| 20 | Group Title 20 | 12 |
+----------+----------------+------------+
profile_id links to FK in table profile:
+------------+------------------+
| profile_id | profile_title_id |
+------------+------------------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| ... | ... |
| 11 | 1 |
| 12 | 5 |
+------------+------------------+
profile_title_id links to FK in table profile_title:
+------------------+-----------------------+
| profile_title_id | title |
+------------------+-----------------------+
| 1 | Profile Title 1 |
| 2 | Profile Title 2 |
| 3 | Profile Title 3 |
| 4 | Profile Title 4 |
| ... | ... |
| 10 | Profile Title 10 |
+------------------+-----------------------+
I have trouble with JOIN.
Here is what i want to get as result:
+----------+----------------+-------------------+-------------------+
| group_id | title | profile_title_id | profile_title |
+----------+----------------+-------------------+-------------------+
| 1 | Group Title 1 | 1 | Profile Title 1 |
| 2 | Group Title 2 | 1 | Profile Title 1 |
| 3 | Group Title 3 | 2 | Profile Title 2 |
| 4 | Group Title 4 | 2 | Profile Title 2 |
| ... | ... | ... | ... |
| 20 | Group Title 20 | 5 | Profile Title 5 |
+----------+----------------+-------------------+-------------------+
But I am only get first 3 columns of what I want to get (group_id, title and profile_title_id). How can I add profile_title to my result? My query now:
SELECT
`group`.`group_id`,
`group`.`title`,
`profile`.`profile_title_id`
FROM `group`
LEFT JOIN `profile` ON `group`.`profile_id` = `profile`.`profile_id`
I was trying this query, but it returns an error (#1066 - Not unique table/alias: 'profile'):
SELECT
`group`.`group_id`,
`group`.`title`,
`profile`.`profile_title_id`,
`profile_title`.`title`
FROM `group`
LEFT JOIN `profile` ON `group`.`profile_id` = `profile`.`profile_id`
LEFT JOIN `profile` ON `group`.`profile_id` = `profile`.`profile_title_id`
Would love any suggestions, thanks!
It looks like you're joining profile twice when you should be joining on profile_title in the second left join:
SELECT
`group`.`group_id`,
`group`.`title`,
`profile`.`profile_title_id`,
`profile_title`.`title`
FROM `group`
LEFT JOIN `profile` ON `group`.`profile_id` = `profile`.`profile_id`
LEFT JOIN `profile_title` ON `profile`.`profile_title_id` = `profile_title`.`profile_title_id`
As for the error in your question - When joining the same table more than once you must alias the tables in order to distinguish between them.
note you can alias any table you're selecting from, basically it allows for a "shortcut" when referencing the table, or a way to uniquely identify tables in your query should there be multiple by the same name.
table aliases can be written like:
select *
from 'group' as g
in the above query, you could reference columns by g rather than group.
Please try something like:
SELECT
`group`.`group_id`,
`group`.`title`,
`profile`.`profile_title_id`,
`profile_title`.`title`
FROM `group`
LEFT JOIN `profile` ON `group`.`profile_id` = `profile`.`profile_id`
LEFT JOIN `profile_title` ON `profile`.`profile_title_id ` = `profile_title`.`profile_title_id`

Inner Join not working after two rows?

Here is my query and it's not showing the 3rd row even though the tables contents match.
SELECT shopcategory_idcategory_name
FROM shopcategory
INNER JOIN category ON shopcategory_id=category_id;
Result:
================================================================
| shopcategory_id | shopcategory_shopid | category_name |
================================================================
| 1 | 1 | Gadgets |
| 2 | 2 | Analog Device |
================================================================
Here is my query that shows it has 3 rows
SELECT * FROM shopcategory;
Result:
===================================================================
| shopcategory_id | shopcategory_shopid | shopcategory_categoryid |
===================================================================
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
===================================================================
EDIT: Query for my category table
SELECT * category;
Result:
==============================================
| category_id | category_name |
==============================================
| 1 | Gadgets |
| 2 | Analog Device |
| 3 | Beauty |
| 4 | Keyboard |
| 5 | Instruments |
| 6 | Monitor |
| 7 | Chairs |
==============================================
You should use LEFT JOIN here instead and add aliases for tables that you are joining on, like this:
SELECT
tableName1.shopcategory_id,
tableName1.category_name,
tableName2.category_id
FROM
tableName1 as tb1
LEFT JOIN
tableName2 AS tb2
ON
tb1.shopcategory_id = tb2.category_id
GROUP BY
tb1.shopcategory_id;

mysql - join problem

I have two tables like below,
mysql> select * from Books ;
+----+------+------------+----------+----------+
| id | name | author_name| category | category2|
+----+------+------------+----------+----------+
| 1 | 1 | Steve | CT001 | CT003 |
| 2 | 2 | John | CT002 | CT002 |
| 3 | 3 | Larry | CT003 | CT002 |
| 4 | 3 | Michael | CT004 | CT004 |
| 5 | NULL | Steven | CT005 | CT005 |
+----+------+------------+----------+----------+
mysql> select * from Codemst ;
+----+------+------------+
| id | code | name |
+----+------+------------+
| 1 | CT001| fiction |
| 2 | CT002| category1 |
| 3 | CT003| etc |
| 4 | CT004| etc2 |
| 5 | CT005| etc3 |
+----+------+------------+
I want to get human readable category name when I query like "select * from Books;"
If there was only one category in the Books table, I think I can use "Join" but, in this case what can I do?
select * from Books b
Inner Join Codemst c1 on b.category = c1.code
inner join codemst c2 on b.category2 = c2.code;
c1.name will hold the readable category, and c2.name the readable category2