web-dev-qa-db-ja.com

where句と結合する

設定テーブルからすべてのデフォルト設定を取得する必要がありますが、x文字が存在する場合は文字設定も取得する必要があります。

しかし、このクエリは、character = 1の設定を取得するだけで、ユーザーが誰も設定していない場合のデフォルト設定は取得しません。

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

だから私はこのようなものが必要です:

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

キー0に文字値を含むデフォルト値が含まれている場合、キー1と2はデフォルト値です。

131
Sein Kraft

where節は、left joinが成功しなかった行を除外しています。結合に移動します。

SELECT  `settings`.*, `character_settings`.`value`
FROM    `settings`
LEFT JOIN 
       `character_settings` 
ON     `character_settings`.`setting_id` = `settings`.`id`
        AND `character_settings`.`character_id` = '1'  
293
Andomar

OUTER JOIN(ANSI-89またはANSI-92)を作成する場合、ON句で指定された基準が適用されるため、フィルタの場所が重要になりますJOINが作成される前WHERE句に指定されたOUTER JOINedテーブルに対する基準が適用されますJOINが作成された後。これにより、まったく異なる結果セットが生成される可能性があります。それとは対照的に、条件がON句またはWHERE句で指定されている場合は、INNER JOINには関係ありません。結果は同じになります。

  SELECT  s.*, 
          cs.`value`
     FROM SETTINGS s
LEFT JOIN CHARACTER_SETTINGS cs ON cs.setting_id = s.id
                               AND cs.character_id = 1
49
OMG Ponies

私があなたの質問を正しく理解しているならば、それらがcharacter_settingsテーブルと対になる結合を持っていないか、またはその結合されたレコードがcharacter_id = 1を持っているなら、あなたは設定データベースからのレコードが欲しいです。

だからあなたはすべきです

SELECT `settings`.*, `character_settings`.`value`
FROM (`settings`)
LEFT OUTER JOIN `character_settings` 
ON `character_settings`.`setting_id` = `settings`.`id`
WHERE `character_settings`.`character_id` = '1' OR
`character_settings`.character_id is NULL
17
Mark

単純な副照会を使用すると理解しやすくなるかもしれません。

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`

サブクエリはnullを返すことが許されているので、メインクエリのJOIN/WHEREについて心配する必要はありません。

時々、これはMySQLではより速い動作しますが、LEFT JOIN形式と比較してあなたに最適なものを確認してください。

SELECT s.*, c.value
FROM settings s
LEFT JOIN character_settings c ON c.setting_id = s.id AND c.character_id = '1'
2
RichardTheKiwi

結果はSQLステートメントに基づいて正しいです。左結合は、右側のテーブルからすべての値を返し、左側のテーブルから一致する値のみを返します。

ID列とNAME列は右側の表からのものであるため、返されます。

スコアは左の表から取得され、この値はName "Flow"に関連するため、30が返されます。他の名前は名前 "Flow"に関連しないためNULLです。

以下はあなたが期待していた結果を返すでしょう:

    SELECT  a.*, b.Score
FROM    @Table1 a
    LEFT JOIN @Table2 b
       ON a.ID = b.T1_ID 
WHERE 1=1
AND a.Name = 'Flow'

SQLは右側のテーブルにフィルタを適用します。

1
Dan