1. 程式人生 > 其它 >一個sql和C#程式碼結合的分組求和的查詢

一個sql和C#程式碼結合的分組求和的查詢

業務描述: 業務主表(tab_main 主鍵 id), 供應商名稱(supplier), 金額(amount 需要統計求和),還有分類( 有單獨的表categoryid),集中採購標記欄位(tenderMark),稽核時間(auditTime)

分類表: (tab_category ),分類id: categoryid,分類名稱:categoryname

主表是明細資料, 要對這個明細 進行統計, 固定列: 供應商名稱,總金額,集採金額, 後面是各個分類的列,有多少個分類,就有多少列(動態的)

現在寫這個sql 思路:

(1) 基礎查詢sourceData

with sourceData as (

selecta.supplier, a.amount, (case whena.tenderMark=1 thena.amount else 0 end) astenderAmount,a.categoryid

where a.auditTime between to_date('2022-01-01 00:00:00',yyyy-mm-dd hi24:mi:ss) andto_date('2022-03-01 00:00:00',yyyy-mm-dd hi24:mi:ss)

)

(2)根據分類 構造 資料集dataALL

with dataALL as (

select 1 as Category0, 0 as Category1, 0 as Category2, 0 as Category3,T.* fromsourceData T wherecategoryid=1

union allselect 0 as Category0, 1 as Category1, 0 as Category2, 0 as Category3,T.*fromsourceDataT wherecategoryid=2

union all select 0 as Category0, 0 as Category1, 1 as Category2, 0 as Category3,T.* fromsourceDataT wherecategoryid=3

union all select 0 as Category0, 0 as Category1, 0 as Category2, 1 as Category3,T.*fromsourceDataT wherecategoryid=3

... --動態的, 有多少個分類 就 重複拼接,通過C#程式碼實現, 構建對應的列資料

)

(4)根據分類,group by

select supplier,sum(amount) asamountSum, sum(tenderAmount) astenderAmountSum

,(case when Category0=1 then sum(amount) else 0 end) asCategory0AmountSum

,(case when Category1=1 then sum(amount) else 0 end) asCategory1AmountSum

,(case when Category2=1 then sum(amount) else 0 end) asCategory2AmountSum

,(case when Category3=1 then sum(amount) else 0 end) asCategory3AmountSum

... --動態拼接

from dataALL group bysupplier,Category0,Category1,Category2,Category3

(5) 之前以為上面就寫完了,後來發現 部署到正式上, 一個供應商對應多條資料出來,

原來當 一個 供應商 有多個分類的時候,資料就會....

那就繼續group by 合併一下

selectsupplier, sum(amountSum)amountSum, sum(tenderAmountSum)tenderAmountSum

,sum(Category0AmountSum)Category0AmountSum

,sum(Category1AmountSum)Category1AmountSum

,sum(Category2AmountSum)Category2AmountSum

,sum(Category3AmountSum)Category3AmountSum

... --動態拼接

from (上面的(4)的查詢 ) newTab

group bysupplier

order bysupplier asc

測試一下資料, 沒問題了,就可以部署了.

上面標記顏色的部分, 是可以用 C#程式碼 進行 迴圈填充的, 多定義幾個 StringBuilder 迴圈 拼接字串.

小結一下: 將複雜的問題 簡單化, 分類為 3個的時候怎麼寫, 4個的時候 怎麼寫,然後推斷成 動態的怎麼拼接 sql.

PS: (1) 我知道有其他的實現方式, 或者什麼 行轉列的 寫法 ,但是好在 我知道我這個業務的分類 不會很多(一般4到6個,不會超過7個)

就這樣簡單寫一下,效率也還行,湊合用,實現效果就行.

(2) 先把資料取出來,然後用C# 程式碼 分組合並, 也是一個思路 ,但是這個 有悖於 開發規範.

一般 資料能在資料庫 裡面操作的, 直接資料庫 裡面操作,資料庫不方便操作的, 拿出來用 C# 程式碼補充操作.

我給這個寫法批2個字: 拙技