programing

왼쪽 결합 위치 절

codeshow 2023. 8. 20. 12:56
반응형

왼쪽 결합 위치 절

설정 테이블에서 모든 기본 설정을 검색해야 하지만 x 문자에 대해 존재하는 경우 문자 설정도 가져와야 합니다.

그러나 이 쿼리는 문자가 = 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')
)

여기서 키 1과 2는 키 0에 문자 값과 함께 기본값이 포함된 경우의 기본값입니다.

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'  

OUTER JOIN(ANSI-89 또는 ANSI-92)을 만들 때 여과 위치는 다음에 명시된 기준 때문에 중요합니다.ONJOIN을 만들기 전에 절이 적용됩니다.에서 제공하는 OUTER JOINED 테이블에 대한 기준WHEREJOIN이 이루어진 후 절이 적용됩니다.이는 매우 다른 결과 집합을 생성할 수 있습니다.이에 비해 INER JOIN의 경우 기준이 아래에 제공되는 것은 중요하지 않습니다.ON또는WHERE절 -- 결과는 동일합니다.

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

만약 내가 당신의 질문을 정확히 이해한다면, 당신은 설정 데이터베이스에서 그들이 character_id 테이블에 대한 조인을 가지고 있지 않거나 그 조인된 레코드가 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

간단한 하위 쿼리를 사용하면 더 쉽게 이해할 수 있습니다.

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에서 이 기능이 더 빨리 작동하는 경우도 있지만 왼쪽 조인 양식과 비교하여 가장 적합한 기능을 확인할 수 있습니다.

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

이 문제의 경우, 내부 조인 테이블의 왼쪽 조인과 같은 사소한 왼쪽 조인과 관련된 다른 많은 경우, 저는 쿼리를 다음과 같이 분할하는 것이 편리하고 다소 가독성이 있다고 생각합니다.with예를 들어,

with settings_for_char as (
  select setting_id, value from character_settings where character_id = 1
)
select
  settings.*,
  settings_for_char.value
from
  settings
  left join settings_for_char on settings_for_char.setting_id = settings.id;

제가 마침내 가장 중요한 답변을 이해하는 방법은 (SQL 쿼리의 실행 순서에 따라) WHERE 절이 결합된 테이블에 적용되어 결합된(또는 출력) 테이블에서 WHERE 조건을 만족하지 않는 행을 필터링한다는 것을 깨닫는 것입니다.그러나 WHERE 조건을 ON 절로 이동하면 결합하기 에 개별 테이블에 적용됩니다.이렇게 하면 왼쪽 테이블의 일부 열 항목(오른쪽 테이블의 항목)이 WHERE 조건을 충족하지 않더라도 왼쪽 테이블의 행을 유지할 수 있습니다.

결과는 SQL 문을 기준으로 정확합니다.왼쪽 조인은 오른쪽 테이블의 모든 값을 반환하고 왼쪽 테이블의 일치하는 값만 반환합니다.

ID 및 NAME 열은 오른쪽 테이블에 있으므로 반환됩니다.

점수는 왼쪽 표에서 나온 것이며, 이 값은 이름 "흐름"과 관련되므로 30이 반환됩니다.다른 이름은 이름 "플로우"와 관련이 없으므로 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은 오른쪽 테이블에 필터를 적용합니다.

언급URL : https://stackoverflow.com/questions/4752455/left-join-with-where-clause

반응형