How to Join Tables By Will Mayall 21-October-2014 Contents Overview ................................................................................................................................................... 1 The Table Definitions .................................................................................................................... 1 Creating the Join .............................................................................................................................. 4 Summary ...................................................................................................................................................... 5 Overview This document is intended to help creating joins on multiple tables. The Table Definitions In this White Paper, the will be 5 tables involved, user, linked_role_user, role, permission, and linked_role_permission. mysql> show create table user\G *************************** 1. row *************************** Table: user Create Table: CREATE TABLE `user` ( `id` mediumint(9) unsigned NOT NULL AUTO_INCREMENT, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `customer_id` mediumint(9) unsigned NOT NULL, `state` tinyint(4) unsigned NOT NULL, `username` varchar(40) NOT NULL, `password_hash` varchar(255) NOT NULL, 1 `password_salt` varchar(10) NOT NULL, `sso_key` varchar(255) NOT NULL, `display_name` varchar(70) NOT NULL, `title` varchar(35) NOT NULL, `email` varchar(255) NOT NULL, `manager_id` mediumint(9) unsigned NOT NULL, `last_state_change_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `user_preferences` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 1 row in set (0.04 sec) mysql> mysql> show create table user\G *************************** 1. row *************************** Table: user Create Table: CREATE TABLE `user` ( `id` mediumint(9) unsigned NOT NULL AUTO_INCREMENT, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `customer_id` mediumint(9) unsigned NOT NULL, `state` tinyint(4) unsigned NOT NULL, `username` varchar(40) NOT NULL, `password_hash` varchar(255) NOT NULL, `password_salt` varchar(10) NOT NULL, `sso_key` varchar(255) NOT NULL, `display_name` varchar(70) NOT NULL, `title` varchar(35) NOT NULL, `email` varchar(255) NOT NULL, `manager_id` mediumint(9) unsigned NOT NULL, `last_state_change_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `user_preferences` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 1 row in set (0.04 sec) 2 mysql> mysql> show create table role\G *************************** 1. row *************************** Table: role Create Table: CREATE TABLE `role` ( `id` tinyint(4) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `description` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 1 row in set (0.01 sec) mysql> mysql> show create table permission\G *************************** 1. row *************************** Table: permission Create Table: CREATE TABLE `permission` ( `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `description` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 1 row in set (0.03 sec) mysql> mysql> show create table link_role_permission\G *************************** 1. row *************************** Table: link_role_permission Create Table: CREATE TABLE `link_role_permission` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `role_id` tinyint(4) unsigned NOT NULL, 3 `permission_id` smallint(5) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 1 row in set (0.02 sec) mysql> Creating the Join The query to join these tables would look like: select u.username,r.name, p.name from user u join link_role_user lru on u.id = lru.user_id join role r on lru.role_id = r.id join link_role_permission lrp on r.id = lrp.role_id join permission p on lrp.permission_id = p.id; +----------+-----------------+----------------------+ | username | name | name | +----------+-----------------+----------------------+ | user | CustomerUser | dashboard | | user | CustomerUser | search | | user | CustomerUser | settings | | user | CustomerUser | password | | user | CustomerUser | logout | | manager | CustomerManager | dashboard | | manager | CustomerManager | search | | manager | CustomerManager | settings | | manager | CustomerManager | password | | manager | CustomerManager | logout | | manager | CustomerManager | manageUsers | | manager | CustomerManager | manageCompanySubsets | | admin | DorgAdmin | logout | | admin | DorgAdmin | settings | | admin | DorgAdmin | api | +----------+-----------------+----------------------+ 15 rows in set (0.00 sec) 4 mysql> Summary Joining multiple tables together can become confusing. Map out the tables on paper, see which columns map to each table. In the above example, Table 1 user Table id Table 2 link_role_user Table id role_id user_id Table 3 role Table id name Table 4 permission Table id name Table 5 link_role_permission Table id role_id permission_id Once you know the relationships between the tables, you can start to build the query. This could take several attempts as I generally have a few typos. 5 In the above example, I join the user.id to the join link_role_user lru on u.id = lru.user_id. Next, I join role r on lru.role_id = r.id. Next, I join link_role_permission lrp on r.id = lrp.role_id. And finally, I join permission p on lrp.permission_id = p.id. Using this approach should help you to build joins to multiple tables. 6