views:

102

answers:

4

I've an old table like this:

user> id | name | address | comments

And now I've to create an "alias" table to allow some users to have an alias name for some reasons. I've created a new table 'user_alias' like this:

user_alias> name | user

But now I have a problem due my poor SQL level... How to join both tables to generate something like this:

1 | my_name    | my_address    | my_comments
1 | my_alias   | my_address    | my_comments
2 | other_name | other_address | other_comments

I mean, I want to make a "SELECT..." query that returns in the same format as the "user" table ALL users and ALL alias.. Something like this:

SELECT user.* FROM user LEFT JOIN user_alias ON `user`=`id`

but it doesn't work for me..

+2  A: 

I think you need something like this:

SELECT user.*
FROM user
LEFT JOIN user_alias
ON user.name=user_alias.name

Your original query was not specific enough in the join condition.

FrustratedWithFormsDesigner
This produces only a single row for id = 1, not two as requested.
Larry Lustig
Yes, not working..
Ivan
Ivan, see my answer, below.
Larry Lustig
+1  A: 
SELECT user.* FROM user LEFT JOIN user_alias ON user.name = user_alias.name
Bryan Denny
A: 

First of all - the query you want to build is not trivial, because you are trying to get some results spanned across more than one row. So I will offer you a proper solution in a fashion like it should be (read: in a way a database developer will do this :-).

First, you should modify your user_alias table so that it will contain id column but not the name. It is not good idea to join your tables using the name field. The reason for this is that there could be two Sarah Connors.

Then, you can get results from both tables using this query:

SELECT user.*, user_alias.*
FROM user LEFT JOIN user_alias
ON user.id=user_alias.id

This way you will get your results in such format:

id | name         | address      | comments   | user
-------------------------------------------------------------
 1 | Sarah Connor | Planet Earth | Nice woman | sarah_connor
 2 | Sarah Connor | USA, NY      | Mean woman | sarah_c
 3 | John Connor  | USA, NY      | n00b       | john123

In the situations when there are two or more records in user_alias table for the same person (equal id's), you will get something like this:

id | name         | address      | comments   | user
-------------------------------------------------------------
 4 | Bill Clinton | White House  | President  | bill
 4 | Bill Clinton | White House  | President  | monica
Andrejs Cainikovs
The problem is that in situations where there is only one alias on file, you will return only one row in the result set. But the OP wants two rows returned (the user row and a separate row combining the alias from user_alias with the address and comment from the matching user row).
Larry Lustig
More generally, the problem is that when there are any aliases at all on file, you will not return the original unaliased row from the user table.
Larry Lustig
+1  A: 

Something like

SELECT user.name, user.address, user.comment FROM user
UNION ALL
SELECT user_alias.alias, user.address, user.comment 
   FROM user INNER JOIN user_alias on user.name = user_alias.name
ORDER BY name

will get you close to what you want.

You need to UNION two SELECTs together because the LEFT JOIN solution proposed by others will include only one row in the result set for users with aliases, not two as specified in your question.

But you should make the common column joining user and alias the id column, not the name column.

Larry Lustig
Perfect! This is the solution. I don't know if this is the best, but it works! Only a small mistake: SELECT user.name, user.address, user.comment FROM userUNION ALLSELECT user_alias.alias, user.address, user.comment FROM user INNER JOIN user_alias on user.id = user_alias.userORDER BY name
Ivan
Oh, I see your JOIN now. You should rename user_alias.user to user_alias.user_id to make it clearer what's going on.
Larry Lustig