[SQL] 사용 LEFT 조인 할 때 어떻게이 스크립트는 테이블을 갱신한다?
SQL사용 LEFT 조인 할 때 어떻게이 스크립트는 테이블을 갱신한다?
이 스크립트의 결과는 정확하지만 이해하지 못하는 것 같습니다 왜 열 BetaStatus 남아 'NOK'
에 대해서는 '베타', 첫 번째 행 (베타 = NOK)는 Summary.BetaStatus @ NOK으로 업데이트 할 것입니다. 그러나 나는 @testTable의 마지막 두 행이 확인에 NOK의 뒤쪽에서 BetaStatus를 업데이트 할 것이라고 생각했다. 난 그냥이 'NOK가'실제로 처리 할 수있는 마지막 행, 따라서 값이다 우연의 일치가 아니라고 확신하고 싶습니다.
declare @testTable table
(
id int,
Pgroup varchar(10),
Pstatus varchar(3)
)
insert into @testTable select 3, 'Alpha', 'OK'
insert into @testTable select 3, 'Beta', 'NOK'
insert into @testTable select 3, 'Gamma', 'OK'
insert into @testTable select 3, 'Beta', 'OK'
insert into @testTable select 3, 'Beta', 'OK'
declare @Summary table
(
id int,
AlphaStatus varchar(3),
BetaStatus varchar(3),
GammaStatus varchar(3)
)
insert into @Summary (id) select 3
update @Summary
set
AlphaStatus = ISNULL(rA.Pstatus, AlphaStatus),
BetaStatus = ISNULL(rB.Pstatus, BetaStatus),
GammaStatus = ISNULL(rG.Pstatus, GammaStatus)
from @Summary t
left join @testTable rA on rA.id = t.ID AND rA.Pgroup = 'Alpha'
left join @testTable rB on rB.id = t.ID AND rB.Pgroup = 'Beta'
left join @testTable rG on rG.id = t.ID AND rG.Pgroup = 'Gamma'
select * from @summary
물어 그 이유는 이전했다 'NOK'경우, AlphaStatus는, BetaStatus는 GammaStatus는 'OK'으로 다시 변경해야하는 것이 아닌 모든 id 인 것을입니다. 이 'NOK'업데이트 일단 관계없이 다음에 오는 어떤 그런 식으로 남아있다.
대안은 'OK'값 @Summary 업데이트 한 다음 'NOK'로 또 다른 갱신을 할 수 있었다. 그런 식으로 나는 'NOK가'교체되지 않습니다 것을 알고있다. 그러나이 작품 있다면, 차라리이를 사용하십시오.
나는 내부 조인 사용하는 경우 그리고 두 번째 질문으로 왜 제대로 업데이트 작동하지 않는 이유는 무엇입니까?
감사.
해결법
-
==============================
1.하자가 반환 대신 업데이 트의 선택을 확인
하자가 반환 대신 업데이 트의 선택을 확인
select AlphaStatus = ISNULL(rA.Pstatus, AlphaStatus), BetaStatus = ISNULL(rB.Pstatus, BetaStatus), GammaStatus = ISNULL(rG.Pstatus, GammaStatus) from @Summary t left join @testTable rA on rA.id = t.ID AND rA.Pgroup = 'Alpha' left join @testTable rB on rB.id = t.ID AND rB.Pgroup = 'Beta' left join @testTable rG on rG.id = t.ID AND rG.Pgroup = 'Gamma'
결과:
AlphaStatus BetaStatus GammaStatus OK NOK OK OK OK OK OK OK OK
이제 UPDATE를 수행하려고
update @Summary set AlphaStatus = ISNULL(rA.Pstatus, AlphaStatus), BetaStatus = ISNULL(rB.Pstatus, BetaStatus), GammaStatus = ISNULL(rG.Pstatus, GammaStatus) from @Summary t left join @testTable rA on rA.id = t.ID AND rA.Pgroup = 'Alpha' left join @testTable rB on rB.id = t.ID AND rB.Pgroup = 'Beta' left join @testTable rG on rG.id = t.ID AND rG.Pgroup = 'Gamma'
업데이트 테이블 @Summary에 포함 된 후 :
id AlphaStatus BetaStatus GammaStatus 3 OK NOK OK
난 당신이 얻고 싶었다 가정 :
id AlphaStatus BetaStatus GammaStatus 3 OK OK OK
그러나 UPDATE는 여러 일치하는 경우 결과가 일치하지 않을 수 있습니다 그것은 부분적으로 테이블 주문 또는 실제 실행 계획을 기반으로, 그런 식으로 작동하지 않습니다.
참조 : FROM하자 지원 중단 UPDATE! 휴고 Kornelis로
너무 대신 테이블 변수 사용 테이블의 불일치를 확인하고 클러스터 된 인덱스를 만들 :
SqlFiddleDemo
CREATE TABLE testTable(id int, Pgroup varchar(10), Pstatus varchar(3)); CREATE CLUSTERED INDEX clx_name ON testTable(PStatus DESC); /* or */ CREATE CLUSTERED INDEX clx_name ON testTable(PStatus ASC);
당신은 예를 들어 MERGE를 사용하는 경우 :
;WITH cte as (SELECT ra.id ,AlphaStatus = rA.Pstatus ,BetaStatus = rB.Pstatus ,GammaStatus = rG.Pstatus from @Summary t left join @testTable rA on rA.id = t.ID AND rA.Pgroup = 'Alpha' left join @testTable rB on rB.id = t.ID AND rB.Pgroup = 'Beta' left join @testTable rG on rG.id = t.ID AND rG.Pgroup = 'Gamma' ) MERGE @Summary AS TGT USING (SELECT * FROM cte ) AS SRC ON TGT.id = SRC.id WHEN MATCHED THEN UPDATE SET AlphaStatus = ISNULL(src.AlphaStatus, tgt.AlphaStatus), BetaStatus = ISNULL(src.BetaStatus, tgt.BetaStatus), GammaStatus = ISNULL(src.GammaStatus, tgt.GammaStatus);
이 허용되지 않는 것이 분명 오류 메시지가 나타납니다 :
from https://stackoverflow.com/questions/32385665/how-is-this-script-updating-table-when-using-left-joins by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 동적 SQL을 사용하면 간단한 SQL 쿼리에 변수를 추가하여 열 이름을 지정합니다 (0) | 2020.07.12 |
---|---|
[SQL] 어떻게 SQL 작업이 성공적으로 실행 여부를 C #의 여부를 확인하는 (0) | 2020.07.12 |
[SQL] , 허용 널 (null)을 하나 개의 테이블에있는 모든 항목을 선택하고 다른 테이블과 조인 (0) | 2020.07.12 |
[SQL] 여러 삽입 SQL 오라클 (0) | 2020.07.12 |
[SQL] MySQL의에서 선택 동적 열 (0) | 2020.07.12 |