天天看點

MS SQL 挑戰問題

群裡面有位網友提出了這樣一個SQL挑戰問題(原話不是這樣,為了說明問題,我略做調整些):

問題說明如下

有一條個銷售報表TEST :

商品 金額

A 1400

B 800

C 790

... ...

現在有這樣一個需求(要寫一個SQL取出如下資料):先按銷售金額倒叙排序,然後從這個報表取出前N條記錄,并且這N條記錄的銷售金額之和是總金額的80%(<= 80%), 80%将作為一個查詢條件(有可能是20%,30%).他的想法是用嵌套函數 遞歸做法記錄砍掉一半判斷是否達到百分比 如果不足再取後半部分的一半 類似這樣的方法;還有就是逐行金額相加當金額到達80%的時候 記錄就從頭顯示到該條的前一條。 現在他想有沒有其他跟高效的方法來實作這個需求?

那麼我看到這個問題的時候,覺得有嵌套函數遞歸處理的方法的效率肯定是最低的,畢竟SQL不擅長于做邏輯處理。那麼有沒有更好的方法來實作呢?大家在看後面方法的時候,可以思考一下有沒有更好的方法,能夠達到一擊必殺的效果(一個SQL搞定)。歡迎大家探讨!

下面是我的一個解決思路和方法,我在按銷售金額倒叙排列的時候,能否得到一個銷售金額的累加值?然後把這個累加值除以銷售總金額即得到累加金額占總金額的一個比例,然後我們再加上查詢條件。即可解決問題。

建立一個測試表TEST

插入測試資料

Code Snippet

INSERT INTO TEST

SELECT 'A' ,13000 UNION ALL

SELECT 'A' ,12000 UNION ALL

SELECT 'A' ,9000 UNION ALL

SELECT 'B' ,167000 UNION ALL

SELECT 'B' ,137000 UNION ALL

SELECT 'B' ,107000 UNION ALL

SELECT 'C' ,78000 UNION ALL

SELECT 'C' ,12000;

實作銷售金額的累加值字段的腳本(這個腳本效率沒有測試,小量資料應該沒有問題)

SELECT ROW_NUMBER() OVER (ORDER BY SALE_AMOUNT DESC ) AS ROW,PRODUCT_NAME,

       T.SALE_AMOUNT,

         (SELECT SUM(SALE_AMOUNT)AS ACCUMATE_SALE FROM TEST WHERE T.SALE_AMOUNT <= SALE_AMOUNT ) AS ACCUMATE_SALE

FROM TEST T

(截圖)

MS SQL 挑戰問題

那麼接下來我們來實作上面的思路

                                     截圖

MS SQL 挑戰問題

接下來就水到渠成了

截圖

MS SQL 挑戰問題

後記總結:其實我們可以用SQL很巧妙的實作很多邏輯複雜的需求,避免我們去做大量複雜的邏輯處理,這就需求我們開動腦筋,挑戰極限。像ITPUT就有很多SQL挑戰問題http://www.itpub.net/forum.php?mod=forumdisplay&fid=3&filter=typeid&typeid=1808 ,國外網站例如http://www.plsqlchallenge.com/, 有興趣的同學盡可去嘗試一下。