iT邦幫忙

0

有關逐日登錄表的資料庫問題請教

  • 分享至 

  • xImage

您好:
想請問一般有關逐日當登錄的紀錄
比如
前日用電量,本日用電量,使用電量
前日用水量,本日用水量,使用水量
這樣的資料表,
再DB端,要如何建構,效能及維護 會較好?
因為還需要 有報表呈現

日期 ,前日電表 ,本日電表,電使用 ,前日水量,本日水量,水使用
20240909 ,100.00 , 120.05 ,20.05 ,200.01 , 201.01 ,1.00
20240910 ,120.05 , 140.05 ,20.00 ,201.01 , 2022.01 ,1.00

目前想直接用此架構來做
也有想 這樣,但整個呈現或計算,就要再 做遞迴取抓資料
日期 ,本日電表,本日水量
20240909 , 120.05 , 201.01

所以想請,前輩們,是否有較好的建議

謝謝

======================== 篩選條件
Force提供的範例
https://stackoverflow.com/questions/58665010/sql-shift-column-down-1-row

https://ithelp.ithome.com.tw/upload/images/20240910/20104095oiiFodMijK.png

看更多先前的討論...收起先前的討論...
froce iT邦大師 1 級 ‧ 2024-09-09 22:58:46 檢舉
https://stackoverflow.com/questions/58665010/sql-shift-column-down-1-row
用正常的就行了
slime iT邦大師 1 級 ‧ 2024-09-10 07:12:32 檢舉
個人建議拆兩個, 甚至三個表.
table_1: 基本抄表資料: 實際上抄錶的時間與數字, 盡量與員工抄表時間一致而非登打時間, 才能反應現場狀況.
table_2: (非必要但建議)換算表: 因為設備有時有單位不同的情況, 用換算表才能正確比較, 也可以在table_1有{原始抄錶數字, 原始單位, 換算抄錶數字, 換算單位}, 讓換算單位一致.
table_3: 計算日用量, 因為有些工廠週六日不上班, 就要考慮週一抄錶跟週五抄錶, 要平均或只計算在週五, 或者不平均, 而是紀錄3日共用了多少. 另外這部分也牽涉要以上班8:00當基準, 或抄表時間當基準, 或半夜0:00當基準.

因為抄表很單純是技術員工作, 計算用量則可能是管理單位需要, 所以建議拆開, 以後統計(日報表衍生月報表等)也比較方便.
slime iT邦大師 1 級 ‧ 2024-09-10 07:14:38 檢舉
計算日用量就可以在抄錶登打後觸法執行計算, 或每日定時計算.
這個用量對一般資料庫來說都很小, 基本上先以好理解跟維護先考慮.
noway iT邦研究生 2 級 ‧ 2024-09-10 09:24:54 檢舉
To Force:
請問,正常是?
我看他的TABLE, 有日期,目前量,前日量; 但資料 ( 目前量,前日量 都打一樣 )
只是後面用視窗行函數去計算?

那跟 目前量,前日量 ,再加一個計算欄位, 或空欄位(前端算完,回填)
效能有比好嗎?

目前,想的是比如一筆RECORE,有20幾個 numeric(18,2) 欄位,且都計算好
與 一筆RECORE 減少5個【結果欄位】,
或者 縮減一半,再去視窗行函數處理,

效能上,與查詢上,差異 ?
謝謝
我建議的做法如下
表用量
抄表日 表號 度數
搜尋語法
找 區間度數
選擇 合計(度數), 表號 從 抄表日 再 A 跟 B 之間 群組 by 表號
基本上不要太爛的機器,例如286電腦,你要計算 一萬筆資料,可能都只要幾秒鐘而已
但現代應該不可能有人用 286電腦來當資料庫主機了
一萬筆等於 27年,假設你有三個電號也是九年,如果九個也有三年
froce iT邦大師 1 級 ‧ 2024-09-10 10:13:08 檢舉
就每天照表抄就好。
Lag會幫你位移,這樣你會有前一日,相減就有每日用量。
要注意先限定好時間再移
noway iT邦研究生 2 級 ‧ 2024-09-10 10:39:27 檢舉
您說的 注意先限定好時間再移?
是指要減一日嗎? 如上圖 補充
下條件的的話,前一天就不見了
slime iT邦大師 1 級 ‧ 2024-09-10 10:59:07 檢舉
個人建議:
Table_1
序號(系統產生), 抄表日, 抄表時間(Option), 表號(自訂), 抄表數值, 抄表單位(由表號帶入), 換算數值(Option), 換算單位(Option), 輸入日期時間(系統產生), 作廢與否(隱藏)

Table_2:
序號(系統產生), 表號, 使用基準日, 結算單位, 結算數值, 對照抄表起日, 對照抄表起數值, 對照抄表起單位, 對照抄表迄日, 對照抄表迄數值, 對照抄表迄單位, 計算或輸入日(系統產生), 作廢與否(隱藏)

用法:
1. 抄錶人只看表號跟數值.
2. 工程師變更表時要維護表號跟單位.
3. 系統對不同單位但同類型的表, 輸入後有換算功能.
4. 定期產生用量表時, 才撈原始資料計算用量.
5. 預留可能修正或調整, 但原始資料不可刪, 所以同樣的表跟時間可能有不同紀錄.
froce iT邦大師 1 級 ‧ 2024-09-10 20:55:05 檢舉
我覺得我說的已經夠清楚了...
LAG的話你要先限定你要的時間區間,然後去位移,這樣不就多了一欄上筆紀錄的數值?
比較要注意的是休假的處理,這要看你的報表怎麼要,要我的話會額外寫一隻程式去定時檢查今天有沒有輸入,沒有的話就把前一筆值照抄一次進去。
noway iT邦研究生 2 級 ‧ 2024-09-11 08:59:40 檢舉
謝謝您的指導
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

2
rogeryao
iT邦超人 7 級 ‧ 2024-09-10 12:13:59
最佳解答
create table aa (
a1 varchar(20), --日期
a2 int,         --類別:1.電,2水
a3 float,       --度數
);

insert into aa
Values
('2021-05-09',1,2376.1),
('2021-05-10',1,2396.4),
('2021-05-11',1,2403.9),
('2021-05-12',1,2413.8),
('2021-05-13',1,2415.6),
('2021-05-10',2,12396.5),
('2021-05-11',2,12453.8),
('2021-05-12',2,12493.3),
('2021-05-13',2,12515.7),
('2021-05-14',2,12625.2);
WITH CTE01 AS (
SELECT a1 AS 'XDate',a2 AS 'XType',
lag(a3, 1, a3) OVER (PARTITION BY a2 ORDER BY a2,A1) as 'PreDegree',
a3 AS 'Degree',
ROUND(a3-lag(a3, 1, a3) OVER (PARTITION BY a2 ORDER BY a2,A1),2) AS 'Qty'
FROM aa  
)

SELECT Distinct S.XDate,
P.PreDegree AS P_PreDegree,P.Degree AS P_Degree,P.Qty AS P_Qty,
W.PreDegree AS W_PreDegree,W.Degree AS W_Degree,W.Qty AS W_Qty
FROM CTE01 AS S
LEFT JOIN CTE01 AS P ON P.XDate=S.XDate AND P.XType = 1
LEFT JOIN CTE01 AS W ON W.XDate=S.XDate AND W.XType = 2
-- WHERE  S.XDate>= '2021-05-11' and S.XDate<= '2021-05-13'
ORDER BY S.XDate

Demo

參考資料:如何將今日最後一筆數值扣掉昨日最後一筆數值?

看更多先前的回應...收起先前的回應...
noway iT邦研究生 2 級 ‧ 2024-09-10 14:27:49 檢舉

您好:
所以 目前常用的作法是
少欄位, 再去撈出資料?

因為較好奇的是,比如 有兩個抄表欄位 (要手動加擴充欄位)
1.直接把拉滿,後續直接看
日期,水前日,水當日,使用水,電前日,電當日,使用電

2.只有抄表欄位 (類別可擴充性)
日期, 水/電類別,抄表值
要看時,再用VIEW 來看

這樣 當欄位多時(20個項目),日期量多時 會差多少
謝謝

rogeryao iT邦超人 7 級 ‧ 2024-09-10 14:47:08 檢舉

戲法人人會變,各有巧妙,端看你的資料結構怎麼定義,SQL 如何下.
這類的問題不外乎使用 lag 來計算上下筆的差值,
或者單純紀錄抄表的數據,在使用 trigger 存檔時寫到另一個 Table (或是上一筆的另一個欄位),
這樣也可算出差值.

基本的原則是 SQL 不要太複雜(未必要使用 View)

不明
【**此則訊息已被站方移除**】
noway iT邦研究生 2 級 ‧ 2024-09-11 08:58:29 檢舉

謝謝

1
stevensmile001
iT邦新手 5 級 ‧ 2024-09-09 20:31:18

不是很 catch 到你的意思
但如果是要減少運算的問題
使用 computed pattern 去設計或許是一個方式
並且在 query 一段時間區間的資料時
在資料本身加入對應使用參數的 index 也是一個簡單可以大幅增加效能的方式
善加使用正確的 query 語法也可以大幅優化效能

我要發表回答

立即登入回答