Reputation: 2142
I'm not even sure of the correct terminology here. MySQL newbie, more or less.
Given a couple tables defined as follows:
CREATE TABLE users
( user_id int(11) NOT NULL auto_increment
, name VARCHAR(255)
, pri_location_id mediumint(8)
, sec_location_id mediumint(8)
, PRIMARY KEY (user_id)
);
CREATE TABLE locations
( location_id mediumint(8) NOT NULL AUTO_INCREMENT
, name varchar(255)
, PRIMARY KEY (location_id)
)
I'm trying to do a query to get the user name and both primary and secondary locations in one go.
I can get one like this:
SELECT u.name AS user_name, l.name as primary_location FROM users u, locations l WHERE u.primary_location_id=l.location_id
But I'm drawing a total blank on the correct syntax to use to get both in one query.
Upvotes: 0
Views: 327
Reputation: 71384
First of, I would strongly consider changing your DB schema if allowable to add a users_locations
table that can be used to properly describe this many to many relationship.
This table could look like:
user_id location_id location_type
1 1 primary
1 2 secondary
2 1 secondary
2 2 primary
and so forth.
You would likely want a compound primary key across all three columns. And location_type might best be enum data type.
Your query would then be like
SELECT
u.name AS user_name
l.name AS location_name
ul.location_type AS location_type
FROM users AS u
INNER JOIN user_location AS ul /* possibly use left join here if user can exist without a location */
ON u.user_id = ul.user_id
INNER JOIN locations AS l
ON ul.location_id = l.location_id
ORDER BY ul.location_type ASC
This would return up to two records per user (separate record for primary and secondary, primary listed first)
If you need this collapsed to a single record you could do this:
SELECT
u.name AS user_name
COALESCE(CASE WHEN ul.location_type = 'primary' THEN l.name ELSE NULL END CASE) AS primary_location,
COALESCE(CASE WHEN ul.location_type = 'secondary' THEN l.name ELSE NULL END CASE) AS secondary_location
FROM users AS u
INNER JOIN user_location AS ul /* possibly use left join here if user can exist without a location */
ON u.user_id = ul.user_id
INNER JOIN locations AS l
ON ul.location_id = l.location_id
GROUP BY `user_name`
If however you are stuck with current schema, then solution by @Jlil should work for you.
Upvotes: -1
Reputation: 170
SELECT u.name AS user_name, l1.name as primary_location , l2.name as secondary_location
FROM users u
JOIN locations l1 ON(u.pri_location_id=l1.location_id)
JOIN locations l2 ON(u.sec_location_id = l2.location_id);
Upvotes: 2