Alex Rivera | Logout

Left Join With Where Clause

Asked 2011-01-20T20:52:47.713
263

I need to retrieve all default settings from the settings table but also grab the character setting if exists for x character.

But this query is only retrieving those settings where character is = 1, not the default settings if the user havent setted anyone.

SELECT `settings`.*, `character_settings`.`value`
FROM (`settings`)
LEFT JOIN `character_settings` 
ON `character_settings`.`setting_id` = `settings`.`id`
WHERE `character_settings`.`character_id` = '1'  

So i should need something like this:

array(
    '0' => array('somekey' => 'keyname', 'value' => 'thevalue'),
    '1' => array('somekey2' => 'keyname2'),
    '2' => array('somekey3' => 'keyname3')
)

Where key 1 and 2 are the default values when key 0 contains the default value with the character value.

Edit
Report

2 Answers

99

When making OUTER JOINs (ANSI-89 or ANSI-92), filtration location matters because criteria specified in the ON clause is applied before the JOIN is made. Criteria against an OUTER JOINed table provided in the WHERE clause is applied after the JOIN is made. This can produce very different result sets. In comparison, it doesn't matter for INNER JOINs if the criteria is provided in the ON or WHERE clauses -- the result will be the same.

  SELECT  s.*, 
          cs.`value`
     FROM SETTINGS s
LEFT JOIN CHARACTER_SETTINGS cs ON cs.setting_id = s.id
                               AND cs.character_id = 1
answered 2011-01-20T21:03:34.133
5

You might find it easier to understand by using a simple subquery

SELECT `settings`.*, (
    SELECT `value` FROM `character_settings`
    WHERE `character_settings`.`setting_id` = `settings`.`id`
      AND `character_settings`.`character_id` = '1') AS cv_value
FROM `settings`

The subquery is allowed to return null, so you don't have to worry about JOIN/WHERE in the main query.

Sometimes, this works faster in MySQL, but compare it against the LEFT JOIN form to see what works best for you.

SELECT s.*, c.value
FROM settings s
LEFT JOIN character_settings c ON c.setting_id = s.id AND c.character_id = '1'
answered 2011-01-20T21:07:34.257

Your Answer