採用SQL交集查詢解決複雜模式物業收費統計

 

          物業收費一般根據國家《物業管理條例》分爲兩種類型,

        第一種:用戶消耗的水電用量

         在一個收費期段內,根據水錶,電錶計量的消耗量乘以單價,就是水電費。這種歸類原因,主要是有計量消耗量數據的儀表。

         第二種:用戶期段內的服務費

         例如:物業管理費,電梯費,衛生費等。這些費用計算的標準大多通過一個時間期段(如:每月、每天、每季度、每年等)還有用戶住房的面積,住戶人數等相關參數,來合理確定收費標準。

比如:衛生費由於住戶的常住人口多,產生的生活垃圾等就多所以在收取衛生費的時候就要求將住戶人數作爲一個參數,這樣收費對大多數用戶來說更合理公平。

         下面來談下業務邏輯的數據庫設計和實現。

         基本信息表

         ‍

          查詢視圖

          ‍

          這裏的設計內容比較多,大家都能設計出更好的。

          我主要介紹下“視圖_物業應交”這個視圖的設計。   

           先提出點問題,算是引子

          按照時間間隔收費,這個時間的間隔一般分爲:“每月一次|每年一次|每天一次|每季度一次   ”四種,在實現SQL查詢集合中就需要判斷處理來解決,一種就是上一篇文章提到的IIF()函數。http://hi.baidu.com/chinameter/blog/item/00732b81f9b330c9bd3e1ef3.html

在由於收取的物業項目很有可能和住戶的面積及常住人口數量有關係,所以設計這種嵌套的判斷邏輯關係可讀性,就變的異常複雜。

           通過思考我打算採用交集(UNION)來實現,這樣每一種可能定義的收費方式單獨形式交集的一個子集,在把這些子集集合到一起也可以解決複雜嵌套判斷邏輯結構複雜,不容易維護、升級等問題。

             ‍

          

           還有一個要點也等提一下。

          在處理按照每年一次收費的時候,由於時間較長,一般都在自然年(就是新的一年開始後)來收取的,例如:暖氣費大多在供暖前期,例如:11月15日供暖前就已經收取了。若要按照自然年在計算費用,肯定是有滯後性,不符合時間業務管理需求。要動態定義提前月份 和日期來實現這樣的功能,才能和實際相結合有效的處理這樣的特殊情況的業務邏輯中數據庫查詢的實現。

         在一個保持參數信息表中定義連個字段“AMonth”和“ADay”來存儲提前計算的月和日時間信息。

         在子集中通過‍DateSerial()函數模擬 獲得抽象自然年的日期(實際不是這個日期,僅獲得這個日期值後,就可以根據自然年計算時間間隔)在通過 DateDiff()獲得時間間隔。

          ‍‍

         ‍

應用程序界面:

        ‍

       ‍

以下是全部SQL查詢:

SELECT 地址,用戶名稱,編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間,DateDiff('m',開始時間,DATE()) as 數量, DateDiff('m',開始時間,DATE())*單價 AS 應收金額
FROM 視圖_用戶_物業項目
WHERE 收費週期='每月一次' and 乘面積 = 0 and 乘人數 = 0 
UNION SELECT 地址,用戶名稱, 編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間, DateDiff('m',開始時間,DATE()) as 數量, DateDiff('m',開始時間,DATE()) * 單價 * 面積 AS 應收金額

FROM 視圖_用戶_物業項目
WHERE 收費週期='每月一次' and 乘面積 <> 0 and 乘人數 = 0 
UNION SELECT 地址,用戶名稱 ,編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間, DateDiff('m',開始時間,DATE()) as 數量, DateDiff('m',開始時間,DATE()) * 單價 * 人數 AS 應收金額

FROM 視圖_用戶_物業項目
WHERE 收費週期='每月一次' and 乘面積 = 0 and 乘人數 <> 0 
UNION SELECT 地址,用戶名稱, 編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間, DateDiff('m',開始時間,DATE()) as 數量, DateDiff('m',開始時間,DATE()) * 單價 * 人數 * 面積 AS 應收金額

FROM 視圖_用戶_物業項目
WHERE 收費週期='每月一次' and 乘面積 <> 0 and 乘人數 <> 0
ORDER BY 地址, 用戶名稱

UNION SELECT 地址,用戶名稱,編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間,DateDiff('d',開始時間,DATE()) as 數量, DateDiff('d',開始時間,DATE())*單價 AS 應收金額
FROM 視圖_用戶_物業項目
WHERE 收費週期='每天一次' and 乘面積 = 0 and 乘人數 = 0 
UNION SELECT 地址,用戶名稱, 編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間,DateDiff('d',開始時間,DATE()) as 數量, DateDiff('d',開始時間,DATE()) * 單價 * 面積 AS 應收金額

FROM 視圖_用戶_物業項目
WHERE 收費週期='每天一次' and 乘面積 <> 0 and 乘人數 = 0 
UNION SELECT 地址,用戶名稱 ,編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間, DateDiff('d',開始時間,DATE()) as 數量, DateDiff('d',開始時間,DATE()) * 單價 * 人數 AS 應收金額

FROM 視圖_用戶_物業項目
WHERE 收費週期='每天一次' and 乘面積 = 0 and 乘人數 <> 0 
UNION SELECT 地址,用戶名稱, 編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間, DateDiff('d',開始時間,DATE()) as 數量, DateDiff('d',開始時間,DATE()) * 單價 * 人數 * 面積 AS 應收金額

FROM 視圖_用戶_物業項目
WHERE 收費週期='每月一次' and 乘面積 <> 0 and 乘人數 <> 0
ORDER BY 地址, 用戶名稱

UNION SELECT 地址,用戶名稱,編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間,DateDiff('q',開始時間,DATE()) as 數量, DateDiff('q',開始時間,DATE())*單價 AS 應收金額
FROM 視圖_用戶_物業項目
WHERE 收費週期='每季度一次' and 乘面積 = 0 and 乘人數 = 0 
UNION SELECT 地址,用戶名稱, 編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間,DateDiff('q',開始時間,DATE()) as 數量, DateDiff('q',開始時間,DATE()) * 單價 * 面積 AS 應收金額

FROM 視圖_用戶_物業項目
WHERE 收費週期='每季度一次' and 乘面積 <> 0 and 乘人數 = 0 
UNION SELECT 地址,用戶名稱 ,編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間,DateDiff('q',開始時間,DATE()) as 數量, DateDiff('q',開始時間,DATE()) * 單價 * 人數 AS 應收金額

FROM 視圖_用戶_物業項目
WHERE 收費週期='每季度一次' and 乘面積 = 0 and 乘人數 <> 0 
UNION SELECT 地址,用戶名稱, 編號,用戶_ID,電話,區名稱,樓名稱,面積,人數,時間,餘額,物業名稱,收費週期,單價,乘面積,乘人數,開始時間, DateDiff('q',開始時間,DATE()) as 數量, DateDiff('q',開始時間,DATE()) * 單價 * 人數 * 面積 AS 應收金額

FROM 視圖_用戶_物業項目
WHERE 收費週期='每季度一次' and 乘面積 <> 0 and 乘人數 <> 0
ORDER BY 地址, 用戶名稱

UNION SELECT 視圖_用戶_物業項目.地址,視圖_用戶_物業項目.用戶名稱,視圖_用戶_物業項目.編號,視圖_用戶_物業項目.用戶_ID,視圖_用戶_物業項目.電話,視圖_用戶_物業項目.區名稱,視圖_用戶_物業項目.樓名稱,視圖_用戶_物業項目.面積,視圖_用戶_物業項目.人數,視圖_用戶_物業項目.時間,視圖_用戶_物業項目.餘額,視圖_用戶_物業項目.物業名稱,視圖_用戶_物業項目.收費週期,視圖_用戶_物業項目.單價,視圖_用戶_物業項目.乘面積,視圖_用戶_物業項目.乘人數,視圖_用戶_物業項目.開始時間, DateDiff('yyyy',DateSerial(year(視圖_用戶_物業項目.開始時間) , month(視圖_用戶_物業項目.開始時間 ) - system.AMonth , day(視圖_用戶_物業項目.開始時間) - system.ADay),DATE()) as 數量 , DateDiff('yyyy',DateSerial(year(視圖_用戶_物業項目.開始時間) , month(視圖_用戶_物業項目.開始時間 ) - system.AMonth , day(視圖_用戶_物業項目.開始時間) - system.ADay),DATE())*視圖_用戶_物業項目.單價 AS 應收金額
FROM 視圖_用戶_物業項目,system 
WHERE 視圖_用戶_物業項目.收費週期='每年一次' and 視圖_用戶_物業項目.乘面積 = 0 and 視圖_用戶_物業項目.乘人數 = 0
ORDER BY 地址, 用戶名稱 
UNION SELECT 視圖_用戶_物業項目.地址,視圖_用戶_物業項目.用戶名稱,視圖_用戶_物業項目.編號,視圖_用戶_物業項目.用戶_ID,視圖_用戶_物業項目.電話,視圖_用戶_物業項目.區名稱,視圖_用戶_物業項目.樓名稱,視圖_用戶_物業項目.面積,視圖_用戶_物業項目.人數,視圖_用戶_物業項目.時間,視圖_用戶_物業項目.餘額,視圖_用戶_物業項目.物業名稱,視圖_用戶_物業項目.收費週期,視圖_用戶_物業項目.單價,視圖_用戶_物業項目.乘面積,視圖_用戶_物業項目.乘人數,視圖_用戶_物業項目.開始時間,DateDiff('yyyy',DateSerial(year(視圖_用戶_物業項目.開始時間) , month(視圖_用戶_物業項目.開始時間 ) - system.AMonth , day(視圖_用戶_物業項目.開始時間) - system.ADay),DATE()) as 數量 , DateDiff('yyyy',DateSerial(year(視圖_用戶_物業項目.開始時間) , month(視圖_用戶_物業項目.開始時間 ) - system.AMonth , day(視圖_用戶_物業項目.開始時間) - system.ADay),DATE())*視圖_用戶_物業項目.單價 * 視圖_用戶_物業項目.面積 AS 應收金額
FROM 視圖_用戶_物業項目,system 
WHERE 視圖_用戶_物業項目.收費週期='每年一次' and 視圖_用戶_物業項目.乘面積 <> 0 and 視圖_用戶_物業項目.乘人數 = 0
ORDER BY 地址, 用戶名稱 
UNION SELECT 視圖_用戶_物業項目.地址,視圖_用戶_物業項目.用戶名稱,視圖_用戶_物業項目.編號,視圖_用戶_物業項目.用戶_ID,視圖_用戶_物業項目.電話,視圖_用戶_物業項目.區名稱,視圖_用戶_物業項目.樓名稱,視圖_用戶_物業項目.面積,視圖_用戶_物業項目.人數,視圖_用戶_物業項目.時間,視圖_用戶_物業項目.餘額,視圖_用戶_物業項目.物業名稱,視圖_用戶_物業項目.收費週期,視圖_用戶_物業項目.單價,視圖_用戶_物業項目.乘面積,視圖_用戶_物業項目.乘人數,視圖_用戶_物業項目.開始時間, DateDiff('yyyy',DateSerial(year(視圖_用戶_物業項目.開始時間) , month(視圖_用戶_物業項目.開始時間 ) - system.AMonth , day(視圖_用戶_物業項目.開始時間) - system.ADay),DATE()) as 數量 , DateDiff('yyyy',DateSerial(year(視圖_用戶_物業項目.開始時間) , month(視圖_用戶_物業項目.開始時間 ) - system.AMonth , day(視圖_用戶_物業項目.開始時間) - system.ADay),DATE())*視圖_用戶_物業項目.單價 * 視圖_用戶_物業項目.人數 AS 應收金額
FROM 視圖_用戶_物業項目,system 
WHERE 視圖_用戶_物業項目.收費週期='每年一次' and 視圖_用戶_物業項目.乘面積 = 0 and 視圖_用戶_物業項目.乘人數 <> 0
ORDER BY 地址, 用戶名稱 
UNION SELECT 視圖_用戶_物業項目.地址,視圖_用戶_物業項目.用戶名稱,視圖_用戶_物業項目.編號,視圖_用戶_物業項目.用戶_ID,視圖_用戶_物業項目.電話,視圖_用戶_物業項目.區名稱,視圖_用戶_物業項目.樓名稱,視圖_用戶_物業項目.面積,視圖_用戶_物業項目.人數,視圖_用戶_物業項目.時間,視圖_用戶_物業項目.餘額,視圖_用戶_物業項目.物業名稱,視圖_用戶_物業項目.收費週期,視圖_用戶_物業項目.單價,視圖_用戶_物業項目.乘面積,視圖_用戶_物業項目.乘人數,視圖_用戶_物業項目.開始時間, DateDiff('yyyy',DateSerial(year(視圖_用戶_物業項目.開始時間) , month(視圖_用戶_物業項目.開始時間 ) - system.AMonth , day(視圖_用戶_物業項目.開始時間) - system.ADay),DATE()) as 數量 , DateDiff('yyyy',DateSerial(year(視圖_用戶_物業項目.開始時間) , month(視圖_用戶_物業項目.開始時間 ) - system.AMonth , day(視圖_用戶_物業項目.開始時間) - system.ADay),DATE())*視圖_用戶_物業項目.單價 * 視圖_用戶_物業項目.人數 * 視圖_用戶_物業項目.面積 AS 應收金額
FROM 視圖_用戶_物業項目,system 
WHERE 視圖_用戶_物業項目.收費週期='每年一次' and 視圖_用戶_物業項目.乘面積 <> 0 and 視圖_用戶_物業項目.乘人數 <> 0
ORDER BY 地址, 用戶名稱;




  

                                              作者;段利慶(Lee)    QQ:14035344

                                             一卡通水電暖專家

                                              http://www.duanliqing.kudos.cc/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章