Id|Name |EmployeeNumber|DepartmentName|Detail|Mac|Card |CardCrypt|Flag|
--+--------+--------------+--------------+------+---+----------+---------+----+
|chocho |1234 |dep1 |d1 | |1234567890| | |
|yoonyoon |2 |dep2 |d2 | |3500078324| | |
이런 테이블 입니다.
다른 테이블 조인 해서
데이터를 가져와서 해당 테이블에 merge into 하고 싶습니다.
카드값을 기준을 기준으로 해당 카드가 있으면 다른 컬럼 update 없으면 insert 하고 싶습니다.
다른 테이블에서 조인해온 데이터에 카드값이 항상있습니다.
제가 삽입하고 싶은 테이블에도 카드값은 항상있습니다.
원본 테이블 이랑 삽입하는 컬럼이랑 데이터가 같아도 항상 update row가 삽입하는 데이터 만큼 뜹니다.
원본이랑 같으면 무시해야 될것 같아서요....
MERGE INTO VAIUsersUI AS vu USING ( SELECT COALESCE(dp.PersonLastName , N'') + COALESCE(dp.PersonFirstName, N'') AS Name ,dp.PersonID as EmployeeNumber,dp.DepartmentName, dp.PersonMemo as Detail ,dpc.IDRF as Card FROM Data_Person dp LEFT OUTER JOIN Data_Person_Cardholder dpc ON dp.PersonID = dpc.PersonID AND dpc.IDRFUSE = 1) AS b ON (vu.Card = b.Card) WHEN MATCHED THEN UPDATE SET vu.Name = b.Name ,vu.EmployeeNumber = b.EmployeeNumber ,vu.DepartmentName = b.DepartmentName ,vu.Detail = b.Detail,vu.Flag=1 WHEN NOT MATCHED THEN INSERT(Name, EmployeeNumber, DepartmentName,Detail,Card,Flag) VALUES(b.Name, b.EmployeeNumber, b.DepartmentName,b.Detail,b.Card,0) ;
Flag 가 3개있습니다. 해당 플래그를 merge into에서 셋팅할수 있을까요?
플래그 | card | card enc | 설명 |
0 | 존재 | 없음 | 외부 에서 card enc 생성 필요 insert |
1 | 존재 | 존재 | 잘맞음 최종 상태 |
2 | 존재 | 존재 | 외부 에 name 등 다른 데이터 update |
현재 상황
테이블이 2개 있고 테이블의 CardCrypt를 외부에서 생성 해야합니다.
데이터를 이렇게 가지고 있습니다.
테이블1: 이름 사원번호 카드
테이블2: 이름 사원번호 카드 카드enc
enc 생성 서버: 이름 사원번호 카드 카드enc
테이블 2에 테이블1 데이터 삽입
테이블 2에 이름 사원번호 카드 enc 생성 서버에 삽입 카드enc 생성
끝------------
새롭게
테이블 1 수정 발생
테이블 2 에서 update, insert Flag 설정 가능?
발급 서버에서 flag 0은 생성
발급 서버에서 flag 3은 수정 이렇게 하려고 합니다
UPDATE VAIUsersUI SET VAIUsersUI.Name = vt.Name, VAIUsersUI.EmployeeNumber = vt.EmployeeNumber, VAIUsersUI.Flag = vt.Flag FROM ( SELECT vu.Id,vt.Name, vt.EmployeeNumber,vt.DepartmentName,vt.Detail, 3 as Flag FROM VAIUsersUI vu LEFT JOIN VAITT vt ON vu.Card = vt.Card WHERE vu.Name <> vt.Name OR vu.EmployeeNumber <> vt.EmployeeNumber OR vu.DepartmentName <> vt.DepartmentName OR vu.Detail <> vt.Detail ) as vt WHERE vt.Id = VAIUsersUI.Id;
답변 감사드립니다.
또다른 질문인데.....
select join 한 결과를 update 하는 퀴리입니다.
되긴 되는데 뭔가 비효율적으로 짠것 같아서요
VAIUsersUI와 VAITT를 비교해서 특정 컬럼의 데이터가 서로 다르면 VAIUsersUI의 FLAG를 3으로 해주는 쿼리입니다.
UPDATE VAIUsersUI vu SET vu.Name = vt.Name , vu.EmployeeNumber = vt.EmployeeNumber , vu.DepartmentName = vt.DepartmentName , vu.Detail = vt.Detail , vu.Flag = 3 FROM VAITT vt WHERE vu.Card = vt.Card AND ( vu.Name <> vt.Name OR vu.EmployeeNumber <> vt.EmployeeNumber OR vu.DepartmentName <> vt.DepartmentName OR vu.Detail <> vt.Detail ) ;
답변감사합니다.
예쁘게 정리 됐네요
From 안에 서브 퀘리를 join으로 바꿔 주셨는데
어떻게 찾아보면 될까요?
쿼리를 짜다보니 From 안에 서브 퀘리를 많이 쓰게 되는데 보기도 안좋고 성능상 별로 라고....
찾아보니 where 안의 서브 퀴리를 join으로 바꾸는 글은 보입니다.
From 안에 서브 퀘리를 join으로 바꾸는건 못찾아서요.
VAITT가 테스트 테이블 이었고
FROM안에 join이 들어간 서브퀴리를 넣어서 잘 작동합니다.
정리해주셨던것 처럼 From 안에 서브쿼리를 join으로 바꿔보고 싶어서요.
//업데이트로 flag 설정 UPDATE VAIUsersUI SET Name = vt.Name , EmployeeNumber = vt.EmployeeNumber , DepartmentName = vt.DepartmentName , Flag = IIF(CardCrypt IS NULL, 0, 2) FROM (SELECT -- COALESCE(dp.PersonLastName , N'') + COALESCE(dp.PersonFirstName, N'') AS Name ,dp.PersonID,dp.DepartmentName, dp.PersonMemo AS Detail ,dpc.IDRF AS Card CONCAT(dp.PersonLastName,dp.PersonFirstName) AS Name ,dp.PersonID AS EmployeeNumber,dp.DepartmentName, dpc.IDRF AS Card FROM Data_Person dp LEFT OUTER JOIN Data_Person_Cardholder dpc ON dp.PersonID = dpc.PersonID AND dpc.IDRFUSE = 1) vt WHERE VAIUsersUI.Card = vt.Card --AND VAIUsersUI.CardCrypt IS NOT NULL AND ( VAIUsersUI.Name <> vt.Name OR VAIUsersUI.EmployeeNumber <> vt.EmployeeNumber OR VAIUsersUI.DepartmentName <> vt.DepartmentName ) ; // 인서트 조건 카드값으로 INSERT INTO VAIUsersUI (Name,EmployeeNumber,DepartmentName,Card) SELECT vt.Name,vt.EmployeeNumber,vt.DepartmentName,vt.Card FROM (SELECT -- COALESCE(dp.PersonLastName , N'') + COALESCE(dp.PersonFirstName, N'') AS Name ,dp.PersonID,dp.DepartmentName, dp.PersonMemo AS Detail ,dpc.IDRF AS Card CONCAT(dp.PersonLastName,dp.PersonFirstName) AS Name ,dp.PersonID AS EmployeeNumber,dp.DepartmentName, dpc.IDRF AS Card FROM Data_Person dp LEFT OUTER JOIN Data_Person_Cardholder dpc ON dp.PersonID = dpc.PersonID AND dpc.IDRFUSE = 1) vt WHERE NOT EXISTS ( SELECT Card FROM VAIUsersUI vu WHERE vu.Card = vt.Card ) ;
UPDATE VAIUsersUI vu SET Name = CONCAT(dp.PersonLastName, dp.PersonFirstName) , EmployeeNumber = dp.PersonID , DepartmentName = dp.DepartmentName , Flag = IIF(CardCrypt IS NULL, 0, 2) FROM Data_Person dp INNER JOIN Data_Person_Cardholder dpc ON dp.PersonID = dpc.PersonID AND dpc.IDRFUSE = 1 WHERE vu.Card = dpc.IDRF AND ( vu.Name <> CONCAT(dp.PersonLastName, dp.PersonFirstName) OR vu.EmployeeNumber <> dp.PersonID OR vu.DepartmentName <> dp.DepartmentName ) ; INSERT INTO VAIUsersUI (Name, EmployeeNumber, DepartmentName, Card) SELECT CONCAT(dp.PersonLastName,dp.PersonFirstName) AS Name , dp.PersonID AS EmployeeNumber , dp.DepartmentName , dpc.IDRF AS Card FROM Data_Person dp INNER JOIN Data_Person_Cardholder dpc ON dp.PersonID = dpc.PersonID AND dpc.IDRFUSE = 1 LEFT OUTER JOIN VAIUsersUI vu ON dpc.IDRF = vu.Card WHERE vu.Card IS NULL ;
MERGE INTO VAIUsersUI vu USING ( SELECT CONCAT(dp.PersonLastName,dp.PersonFirstName) AS Name , dp.PersonID AS EmployeeNumber , dp.DepartmentName , dpc.IDRF AS Card FROM Data_Person dp INNER JOIN Data_Person_Cardholder dpc ON dp.PersonID = dpc.PersonID AND dpc.IDRFUSE = 1 LEFT OUTER JOIN VAIUsersUI vu ON dpc.IDRF = vu.Card WHERE vu.Card IS NULL OR vu.Name <> CONCAT(dp.PersonLastName, dp.PersonFirstName) OR vu.EmployeeNumber <> dp.PersonID OR vu.DepartmentName <> dp.DepartmentName ) vt ON (vu.Card = vt.Card) WHEN MATCHED THEN UPDATE SET vu.Name = vt.Name , vu.EmployeeNumber = vt.EmployeeNumber , vu.DepartmentName = vt.DepartmentName , vu.Flag = CASE WHEN vu.CardCrypt IS NULL THEN 0 ELSE 2 END WHEN NOT MATCHED THEN INSERT ( Name, EmployeeNumber, DepartmentName, Card, Flag) VALUES (vt.Name, vt.EmployeeNumber, vt.DepartmentName, vt.Card, 0) ;