2017-05-09 1 views
-4

테스트 스터디 가이드에서 가져온 것입니다. 이 쿼리의 목적은 무엇입니까? 이 인쇄 기능은 while 루프의 일부입니까, 아니면 while 루프 후에 만 ​​실행합니까?이 쿼리는 어떤 기능을합니까?

1,000에서 200,000 달러 사이의 인보이스를 삭제하는 것이 목적입니까?

while 루프가 실제로 반복됩니까? 루프가 중단됩니다 합계가 200,000 ....입니다. 송장 총액이 1,000 미만인 경우 루프가 중단됩니다. 총계가 1,000 ~ 200,000 사이 인 경우 루프가 종료됩니다.

USE AP 

SELECT * INTO #InvoiceCopy FROM Invoices 

DECLARE @InvoiceID int, @InvoiceTotal money 
DECLARE @Total money 
SET @Total = 0 

WHILE @Total + (SELECT TOP 1 InvoiceTotal 
       FROM #InvoiceCopy 
       ORDER BY InvoiceTotal DESC) <= 200000 
BEGIN 
    SELECT TOP 1 @InvoiceID = InvoiceID, @InvoiceTotal = InvoiceTotal 
    FROM  #InvoiceCopy 
    ORDER BY InvoiceTotal DESC 

    IF @InvoiceTotal < 1000 
     BREAK 
    ELSE 
    BEGIN 
     SET @Total = @Total + @InvoiceTotal 

     DELETE FROM #InvoiceCopy 
     WHERE InvoiceID = @InvoiceID 
    END 
END 
PRINT 'Total: $' + CONVERT(varchar, @Total, 1) 
+3

좋은 슬픔 무엇을위한 학습 가이드 ??? 이것은 왜 우리가이 두려운 RBAR (row by agonizing row) 유형의 로직 대신에 세트 기반 로직을 사용하고자하는지 보여주는 훌륭한 예입니다. 그리고 그것은 매우 부서지기 쉽습니다. 고안된 값을 초과하지 않는 한 무한 루프가 될 수 있습니다. 교수님은 사람들을 가르치려고하기 전에 실제로 데이터베이스를 배워야합니다. –

+0

롤 ... 그래서 어떻게 느끼나요? 그래, 나는 동의한다. 설상가상으로이 특별한 경우에 자신을 가르치는 것과 거의 같은 온라인 수업입니다. 그것은 자질구레 한 일입니다. 스택 오버 플로우에 대해 하느님 감사합니다. –

+0

나는 너의 고통을 느낀다. 너무 자주 교수들은 강제 사례를 통해 빈약 한 방법론을 가르칩니다. 그것은 학생들과 미래의 고용주들이 새로운 학생들에게 가르쳐 진 고풍의 사고 방식을 해독 할 고통을줍니다. 근본적으로 당신이 작업하고있는 것은 합계입니다. SQL Server의 버전에 따라 while 회 돌이를 사용하는 것보다 더 나은 해결책이 있습니다. –

답변

0

(내가 말할 수있는 것과) 쿼리의 목적은 $ 1000에 의거 한 송장이없는 한, $ 200K에서 모든 송장을 요약하고 전체를 표시하는 것입니다.

USE AP 

DECLARE @Total money 

SELECT * INTO #InvoiceCopy FROM Invoices 

SELECT @Total = SUM(InvoiceTotal) 
FROM #InvoiceCopy 
WHERE InvoiceTotal <= 200000 

PRINT 'Total: $' + CONVERT(varchar, @Total, 1) 

이상한를 : - 당신은 단순히 테이블에 부하를 줄이기 위해 노력하고하지 않는 한,이를 위해 임시 테이블과 루프를 사용하는 이유 단서가 없다 그렇다하더라도,이 쿼리는 정확히 같은 일을 할 것입니다 InvoiceTotal이 $ 1000 미만인 경우 BREAK 부분입니다. 필터를 제거해야합니다. 또는 "불량 데이터"를 나타 내기 때문에 이들을 확인해야 할 필요가있는 경우 루프를 시작하기 전에이 검사를 수행해야합니다.

IF EXISTS (SELECT 1 FROM #InvoiceCopy WHERE InvoiceTotal < 1000) 
    RAISERROR('Invoices under $1000 exist.', 16, 1) 

기본적으로 위의 의견에서 숀이 말한 바는 100 % 정확합니다.이를 수행하는 방법이 훨씬 더 있습니다.

관련 문제