문제

할당된 사람과 현재 단계와 같은 데이터가 포함된 작업 목록이 포함된 뷰가 있습니다.각 단계에서 각 사람이 가지고 있는 작업 수를 반환하는 저장 프로시저를 작성해야 합니다.

지금까지 나는 이것을 가지고 있습니다 (단순화):

DECLARE @ResultTable table 
(
  StaffName nvarchar(100),
  Stage1Count int,
  Stage2Count int
)

INSERT INTO @ResultTable (StaffName, Stage1Count)
  SELECT StaffName, COUNT(*) FROM ViewJob
  WHERE InStage1 = 1
  GROUP BY StaffName

INSERT INTO @ResultTable (StaffName, Stage2Count)
  SELECT StaffName, COUNT(*) FROM ViewJob
  WHERE InStage2 = 1
  GROUP BY StaffName

문제는 행이 결합되지 않는다는 것입니다.따라서 직원이 stage1 및 stage2에 작업을 갖고 있는 경우 @ResultTable에 두 개의 행이 있습니다.제가 정말로 하고 싶은 것은 직원에 대한 행이 있으면 업데이트하고, 없으면 새 행을 삽입하는 것입니다.

누구든지 이 작업을 수행하는 방법을 알고 있거나 다른 접근 방식을 제안할 수 있습니까?나는 사용자 목록을 반복하기 위해 커서를 사용하는 것을 정말로 피하고 싶습니다(그러나 이것이 나의 대체 옵션입니다).

SQL Server 2005를 사용하고 있습니다.

편집하다:@이씨: 불행히도 InStage1 = 1은 단순화되었습니다.이는 DateStarted가 NULL이 아니고 DateFinished가 NULL인 WHERE DateStarted와 비슷합니다.

편집하다:@BCS: 나는 모든 직원을 먼저 삽입하는 아이디어를 좋아하므로 매번 업데이트만 하면 됩니다.하지만 저는 UPDATE 문을 올바르게 작성하는 데 어려움을 겪고 있습니다.

도움이 되었습니까?

해결책

IIRC에는 행이 존재하는 경우 업데이트할 수 있는 일종의 "On Duplicate"(이름이 잘못되었을 수 있음) 구문이 있습니다(MySQL).

또는 다음과 같은 형태도 있습니다.

INSERT INTO @ResultTable (StaffName, Stage1Count, Stage2Count)
  SELECT StaffName,0,0 FROM ViewJob
  GROUP BY StaffName

UPDATE @ResultTable Stage1Count= (
  SELECT COUNT(*) AS count FROM ViewJob
  WHERE InStage1 = 1
  @ResultTable.StaffName = StaffName)

UPDATE @ResultTable Stage2Count= (
  SELECT COUNT(*) AS count FROM ViewJob
  WHERE InStage2 = 1
  @ResultTable.StaffName = StaffName)

다른 팁

사실 지금보다 훨씬 더 열심히 하고 계신 것 같아요.이 코드가 당신이 하려는 일에 작동하지 않나요?

SELECT StaffName, SUM(InStage1) AS 'JobsAtStage1', SUM(InStage2) AS 'JobsAtStage2'
  FROM ViewJob
GROUP BY StaffName

존재 여부를 확인하고 적절한 명령을 사용할 수 있습니다.나는 이것이 실제로 뒤에서 커서를 사용한다고 생각하지만 얻을 수 있는 최고는 다음과 같습니다.

IF (EXISTS (SELECT * FROM MyTable WHERE StaffName = @StaffName))
begin
    UPDATE MyTable SET ... WHERE StaffName = @StaffName
end
else
begin
    INSERT MyTable ...
end 

SQL2008에는 멋진 새로운 MERGE 기능이 있지만 2005에는 없습니다.

실제 "upsert" 유형의 쿼리를 얻으려면 존재하는 경우를 사용해야 합니다...이는 불행하게도 커서를 사용하는 것을 의미합니다.

그러나 두 개의 쿼리를 실행할 수 있습니다. 하나는 기존 행이 있는 업데이트를 수행한 다음 나중에 새 행을 삽입하는 것입니다.소수의 행만 처리하는 경우가 아니라면 이 집합 기반 접근 방식이 더 바람직하다고 생각합니다.

결과 테이블의 다음 쿼리는 행을 다시 결합해야 합니다.이는 InStage1과 InStage2가 둘 다 '1'이 될 수 없다고 가정합니다.

select distinct(rt1.StaffName), rt2.Stage1Count, rt3.Stage2Count
from @ResultTable rt1
left join @ResultTable rt2 on rt1.StaffName=rt2.StaffName and rt2.Stage1Count is not null
left join @ResultTable rt3 on rt1.StaffName=rt2.StaffName and rt3.Stage2Count is not null

BCS의 답변을 변형하여 작동하게 만들었습니다.하지만 테이블 변수를 사용할 수 없으므로 임시 테이블을 만들어야 했습니다.

CREATE TABLE #ResultTable
(
  StaffName nvarchar(100),
  Stage1Count int,
  Stage2Count int
)

INSERT INTO #ResultTable (StaffName)
  SELECT StaffName FROM ViewJob
  GROUP BY StaffName

UPDATE #ResultTable SET 
  Stage1Count= (
    SELECT COUNT(*) FROM ViewJob V
    WHERE InStage1 = 1 AND 
        V.StaffName = @ResultTable.StaffName COLLATE Latin1_General_CI_AS
    GROUP BY V.StaffName),
  Stage2Count= (
    SELECT COUNT(*) FROM ViewJob V
    WHERE InStage2 = 1 AND 
        V.StaffName = @ResultTable.StaffName COLLATE Latin1_General_CI_AS
    GROUP BY V.StaffName)

SELECT StaffName, Stage1Count, Stage2Count FROM #ResultTable

DROP TABLE #ResultTable
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top