好吧,我確實不知道該怎麼起這個標題,整了一個“分佈”,感覺還有點高檔,其實沒啥技術含量,看完你就知道了。情況是這樣,剛剛接到一個臨時任務,需要讓幾個營業點的銷售數據【變】少一點,就是在ERP的相關報表中,查詢出來的數據要在指定區間,說白了就是那什麼~你懂的,某些同行應該對這種任務很熟悉了,而有些同行...
好吧,我確實不知道該怎麼起這個標題,整了一個“分佈”,感覺還有點高檔,其實沒啥技術含量,看完你就知道了。情況是這樣,剛剛接到一個臨時任務,需要讓幾個營業點的銷售數據【變】少一點,就是在ERP的相關報表中,查詢出來的數據要在指定區間,說白了就是那什麼~你懂的,某些同行應該對這種任務很熟悉了,而有些同行可能正在或即將面臨這樣的任務,希望此文能提供一點思路。
我是第一次接到這種任務,感覺蠻新鮮,思量一下,決定在測試庫動手腳,完了讓他的ERP接入測試庫,事情過後再切回正式庫,細枝末節就不說了,重點說一下數據處理方法。根本原理是刪除部分單據,因為報表的數據是從單據來的,單據少了,自然數字就小了(至於單據數據結構,不同的ERP方案當然有不同的設計,刪除一張單涉及的數據修改也不同,我的情況是直接刪除主單就行,細表會自動級聯刪除,當然還有別的關聯數據,那個不用管,反正是測試庫,咋折騰都行,只要讓報表呈現符合預期就好)。為了讓明細數據顯得更自然,當然不能簡單粗暴的把一段連續時期內的單據統統刪除,或者把大量單據的折扣改低以符合目標,那樣太粗暴,弄巧成拙就不好了。
我設想的是,按一定時間粒度(如日、周、月、季度)劃分單據,然後從每個區間內查出一定比例的單據,然後與目標比對,根據比對情況逐步調整粒度與比例,直至符合目標為止。這樣就得到了需要保留的單據,剩下就是把查詢區間內的其餘單據刪除即可。當然也可以將當前數據與目標數據相減,得到需要砍掉的數據,完了以該數據作為目標來查詢單據,這樣就能直接得到需要刪除的單據。我採用的是前一種,即得到需要保留的單據,完了也就一個where not in的事,不費力。上代碼:
WITH cte AS ( --按一定時間粒度分組(日、周、月、季度等) SELECT ROW_NUMBER() OVER(PARTITION BY DATEPART(week, 單據日期) ORDER BY 單據編號) AS 'RowNo' ,DATEPART(week, 單據日期) AS 'Rang', 單據日期, 單據編號, 成交金額 FROM 主單表 WHERE 營業點='xxx' AND YEAR(單據日期)=2015 ),cte2 AS ( --得到每組的單據數,作為分母 SELECT Rang,COUNT(1) AS 'BillCount' FROM cte GROUP BY Rang ) SELECT a.*,BillCount FROM cte a JOIN cte2 b ON b.Rang = a.Rang WHERE RowNo/CAST(BillCount AS DECIMAL(16,4)) < 0.81 --按比例取每組的部分行,billcount是int,需轉換為小數再除
時間粒度就修改datepart函數的第1個參數(day/week/month/quarter等),註意有2處,比例就修改最後那個0.81,很簡單,說一下都多餘。
我的環境是SQL08R2,如果有更正確的姿勢,還望大俠提點,感謝。