Thread: Join several tables (to fetch user info), but one of them is optional (user avatar)
Join several tables (to fetch user info), but one of them is optional (user avatar)
From
Alexander Farber
Date:
Hello, given a user name in a Drupal 7.17 database using PostgreSQL 8.4.13 I am trying to fetch user info (uid, city, gender, avatar) distributed over several tables. The avatar is however optional - some users don't have it. For users, that do have avatars my query works well: # select u.uid, /* u.pass, */ f.filename, g.field_gender_value, c.field_city_value from drupal_users u, drupal_file_managed f, drupal_field_data_field_gender g, drupal_field_data_field_city c where u.name='Alex' and u.picture=f.fid and g.entity_id=u.uid and c.entity_id=u.uid ; uid | filename | field_gender_value | field_city_value -----+--------------------------+--------------------+------------------ 1 | picture-1-1312223092.jpg | Male | Bochum (1 row) However for users, who don't have avatar I get empty result. When I omit the drupal_file_managed table - it works again: # select u.uid, /* u.pass, */ g.field_gender_value, c.field_city_value from drupal_users u, drupal_field_data_field_gender g, drupal_field_data_field_city c where u.name='mvp' and g.entity_id=u.uid and c.entity_id=u.uid ; uid | field_gender_value | field_city_value -------+--------------------+------------------ 18539 | Male | Moscow (1 row) How could I modify my join statement to ensure that it always returns 1 row for valid users - regardless if they have avatar or not? Do I want a "left outer join" here? (I'm afraid it will return several rows instead of 1). Regards Alex
Re: Join several tables (to fetch user info), but one of them is optional (user avatar)
From
Albe Laurenz
Date:
Alexander Farber wrote: > given a user name in a Drupal 7.17 database > using PostgreSQL 8.4.13 I am trying to fetch user info > (uid, city, gender, avatar) distributed over several tables. > > The avatar is however optional - some users don't have it. > > For users, that do have avatars my query works well: > > # select > u.uid, > /* u.pass, */ > f.filename, > g.field_gender_value, > c.field_city_value > from > drupal_users u, > drupal_file_managed f, > drupal_field_data_field_gender g, > drupal_field_data_field_city c > where > u.name='Alex' and > u.picture=f.fid and > g.entity_id=u.uid and > c.entity_id=u.uid > ; > uid | filename | field_gender_value | field_city_value > -----+--------------------------+--------------------+------------------ > 1 | picture-1-1312223092.jpg | Male | Bochum > (1 row) > > However for users, who don't have avatar I get empty result. > > When I omit the drupal_file_managed table - it works again: > > # select > u.uid, > /* u.pass, */ > > g.field_gender_value, > c.field_city_value > from > drupal_users u, > > drupal_field_data_field_gender g, > drupal_field_data_field_city c > where > u.name='mvp' and > > g.entity_id=u.uid and > c.entity_id=u.uid > ; > uid | field_gender_value | field_city_value > -------+--------------------+------------------ > 18539 | Male | Moscow > (1 row) > > How could I modify my join statement to > ensure that it always returns 1 row for valid users - > regardless if they have avatar or not? > > Do I want a "left outer join" here? > (I'm afraid it will return several rows instead of 1). Yes, you need an outer join for that. Only use an outer join to add the "drupal_file_managed" table, the other tables should be joined with an inner join. Yours, Laurenz Albe
Re: Join several tables (to fetch user info), but one of them is optional (user avatar)
From
Alexander Farber
Date:
Thank you, I've ended up with: # select u.uid, /* u.pass, */ f.filename as avatar, (g.field_gender_value='Female') as female, c.field_city_value as city from drupal_users u LEFT OUTER JOIN drupal_file_managed f on (u.picture=f.fid), drupal_field_data_field_gender g, drupal_field_data_field_city c where u.name='mvp' and g.entity_id=u.uid and c.entity_id=u.uid ; uid | avatar | female | city -------+--------+--------+-------------- 18539 | | f | Moscow (1 row) I wonder though what is the syntax if I wanted the other 2 tables (drupal_field_data_field_gender and drupal_field_data_field_city) to be joined as a "left outer join" as well? Regards Alex
Re: Join several tables (to fetch user info), but one of them is optional (user avatar)
From
John R Pierce
Date:
On 12/19/2012 5:54 AM, Alexander Farber wrote: > I wonder though what is the syntax if I wanted > the other 2 tables (drupal_field_data_field_gender > and drupal_field_data_field_city) to be joined > as a "left outer join" as well? you were using an implied join instead of an explicit one. select u.uid, /* u.pass, */ f.filename as avatar, (g.field_gender_value='Female') as female, c.field_city_value as city from drupal_users u JOIN drupal_field_data_field_gender g ON g.entity_id=u.uid JOIN drupal_field_data_field_city c ON c.entity_id=u.uid LEFT JOIN drupal_file_managed f ON u.picture=f.fid where u.name='mvp'; is more like how you code a conventional JOIN.