2017-05-09 30 views
-4

這是來自測試學習指南。這個查詢的目的是什麼?這個打印函數是while循環的一部分還是隻在while循環之後運行?這個查詢有什麼作用?

這是爲了刪除1,000至20萬美元之間的發票嗎?

請問while循環每個實際循環?循環將打破總數高於200,000 ....如果發票總數低於1000,則循環將中斷....如果總數在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(通過令人興奮的行)類型的邏輯的一個很好的例子。它非常脆弱。除非人爲的價值超過,否則它可能會陷入無限循環。你的教授真的應該在他們試圖教人之前學習數據庫。 –

+0

大聲笑...那你怎麼覺得呢?是的,我同意。更糟糕的是,這是一個在線課程,在這種特殊情況下教你自己幾乎相當於。這是一件苦差事。感謝上帝的堆棧溢出。 –

+0

我感到你的痛苦。很多時候,教授們用強迫性的例子來教授差的方法論。這給他們的學生和他們未來的僱主帶來了痛苦,使他們不再去教給新生的古老思維方式。你的工作基本上等於一個運行總數。根據sql server的版本,有比使用while循環更好的解決方案。 –

回答

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) 

基本上,肖恩在上面評論中說的是100%準確的 - 有很多更好的方法來做到這一點。