这个查询有什么作用?

时间:2017-05-09 15:01:36

标签: sql-server

这是来自测试学习指南。这个查询的目的是什么?这个print函数是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)

1 个答案:

答案 0 :(得分:0)

查询的目的(据我所知)是总结所有低于$ 200K的发票并显示总额,除非有1000美元以下的发票。我不知道为什么你会为此使用临时表和循环,除非你只是试图减少该表的负载 - 即使这样,这个查询也会做同样的事情:

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)

基本上,Sean在上面的评论中所说的是100%准确 - 有更好的方法来做到这一点。