sql - not - Izquierda Únete con Where Clause
sql conditions (5)
Necesito recuperar todas las configuraciones predeterminadas de la tabla de configuraciones, pero también tomar la configuración de caracteres si existe para el carácter x.
Pero esta consulta solo recupera aquellas configuraciones donde character = 1, no la configuración predeterminada si el usuario no ha configurado a nadie.
SELECT `settings`.*, `character_settings`.`value`
FROM (`settings`)
LEFT JOIN `character_settings`
ON `character_settings`.`setting_id` = `settings`.`id`
WHERE `character_settings`.`character_id` = ''1''
Entonces debería necesitar algo como esto:
array(
''0'' => array(''somekey'' => ''keyname'', ''value'' => ''thevalue''),
''1'' => array(''somekey2'' => ''keyname2''),
''2'' => array(''somekey3'' => ''keyname3'')
)
Donde las claves 1 y 2 son los valores predeterminados cuando la clave 0 contiene el valor predeterminado con el valor del carácter.
Cuando se realizan UNIONES EXTERNAS (ANSI-89 o ANSI-92), la ubicación de la filtración es importante porque los criterios especificados en la cláusula ON
se aplican antes de que se realice el JOIN . Los criterios contra una tabla OUTER JOINed proporcionada en la cláusula WHERE
se aplica después de que se realiza el JOIN . Esto puede producir conjuntos de resultados muy diferentes. En comparación, no importa INNER JOINs si los criterios se proporcionan en las cláusulas ON
o WHERE
: el resultado será el mismo.
SELECT s.*,
cs.`value`
FROM SETTINGS s
LEFT JOIN CHARACTER_SETTINGS cs ON cs.setting_id = s.id
AND cs.character_id = 1
El resultado es correcto basado en la declaración de SQL. La combinación izquierda devuelve todos los valores de la tabla correcta y solo los valores coincidentes de la tabla izquierda.
Las columnas ID y NAME se encuentran en la tabla lateral derecha, por lo que se devuelven.
La puntuación es de la tabla de la izquierda y se devuelve 30, ya que este valor se relaciona con el nombre "Flujo". Los otros nombres son NULL ya que no se relacionan con Name "Flow".
Lo siguiente arrojaría el resultado que esperabas:
SELECT a.*, b.Score
FROM @Table1 a
LEFT JOIN @Table2 b
ON a.ID = b.T1_ID
WHERE 1=1
AND a.Name = ''Flow''
El SQL aplica un filtro en la tabla de la derecha.
La cláusula where
está filtrando filas donde la left join
no tiene éxito. Moverlo a la unión:
SELECT `settings`.*, `character_settings`.`value`
FROM `settings`
LEFT JOIN
`character_settings`
ON `character_settings`.`setting_id` = `settings`.`id`
AND `character_settings`.`character_id` = ''1''
Puede encontrarlo más fácil de entender usando una subconsulta simple
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`
La subconsulta puede devolver nulo, por lo que no tiene que preocuparse por JOIN / WHERE en la consulta principal.
A veces, esto funciona más rápido en MySQL, pero compáralo con el formulario LEFT JOIN para ver qué funciona mejor para ti.
SELECT s.*, c.value
FROM settings s
LEFT JOIN character_settings c ON c.setting_id = s.id AND c.character_id = ''1''
Si entiendo correctamente su pregunta, quiere registros de la base de datos de configuraciones si no tienen una unión entre la tabla character_settings o si ese registro unido tiene character_id = 1.
Por lo tanto, debes hacer
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