it-swarm.com.de

Linke Join With Where-Klausel

Ich muss alle Standardeinstellungen aus der Einstellungstabelle abrufen, aber auch die Zeicheneinstellung übernehmen, wenn sie für das Zeichen x vorhanden ist.

Diese Abfrage ruft jedoch nur die Einstellungen ab, bei denen das Zeichen = 1 ist, nicht die Standardeinstellungen, wenn der Benutzer keine Einstellungen vorgenommen hat.

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

Also sollte ich so etwas brauchen:

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

Wobei Schlüssel 1 und 2 die Standardwerte sind, wenn Schlüssel 0 den Standardwert mit dem Zeichenwert enthält.

139
Sein Kraft

Die where -Klausel filtert Zeilen weg, in denen die left join gelingt nicht. Verschiebe es in den 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'  
304
Andomar

Bei der Erstellung von OUTER JOINs (ANSI-89 oder ANSI-92) spielt die Filterposition eine Rolle, da die in der ON -Klausel angegebenen Kriterien angewendet werden bevor JOIN erstellt wird. Kriterien für eine OUTER JOINed-Tabelle, die in der WHERE -Klausel angegeben ist, werden angewendet nachdem der JOIN erstellt wurde. Dies kann zu sehr unterschiedlichen Ergebnismengen führen. Im Vergleich dazu spielt es für INNER JOINs keine Rolle, ob die Kriterien in den Klauseln ON oder WHERE angegeben sind - das Ergebnis ist dasselbe.

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

Wenn ich Ihre Frage richtig verstehe, möchten Sie Datensätze aus der Einstellungsdatenbank, wenn sie keine Verknüpfung zur Tabelle character_settings haben oder der verknüpfte Datensatz character_id = 1 hat.

Das solltest du also tun

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

Sie finden es möglicherweise einfacher zu verstehen, wenn Sie eine einfache Unterabfrage verwenden

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`

Die Unterabfrage darf null zurückgeben, sodass Sie sich nicht um JOIN/WHERE in der Hauptabfrage kümmern müssen.

Manchmal funktioniert das schneller in MySQL, aber vergleichen Sie es mit dem LEFT JOIN-Formular, um zu sehen, was für Sie am besten funktioniert.

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

Das Ergebnis ist basierend auf der SQL-Anweisung korrekt. Der Linke Join gibt alle Werte aus der rechten Tabelle und nur die übereinstimmenden Werte aus der linken Tabelle zurück.

ID- und NAME-Spalten stammen aus der rechten Nebentabelle, werden also zurückgegeben.

Die Bewertung stammt aus der linken Tabelle und es werden 30 zurückgegeben, da sich dieser Wert auf den Namen "Flow" bezieht. Die anderen Namen sind NULL, da sie sich nicht auf den Namen "Flow" beziehen.

Das Folgende würde das erwartete Ergebnis zurückgeben:

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

Die SQL wendet einen Filter auf die rechte Tabelle an.

1
Dan