在某些時候要從 SQL Table 中取出資料,資料特性為不重複,且為
目前最新的狀態時,可以使用 ROWNUMBER () 來先進行排序的動作,
再做資料上的篩選;而取資料有時候會用到子查詢,子查詢的方式有許多種,
其中一種為使用 WITH AS () 的片段插入方式來做(CTE)。
假設今天有一張表,當中記錄著每天每台機器所生產的狀況,包含了日期、時間、班別、
相關的材料規格、重量等(表一):
另一張表則記錄著每台機器的資訊,像是規定的生產標準重量、
生產狀況等(表二):
今天想做一個查詢是--->找到每天當下的那個時刻,機器的生產情形。
首先,先針對表一做 ROWNUMBER(),先給予每筆資料進行排序
(WHER設定條件為2017年4月20日,機器為HJ03號,機器的重量不為0)
SELECT MItem AS 機器, YM AS 日期, HR AS 時間 , ROW_NUMBER() OVER(PARTITION BY MItem ORDER BY YM DESC,HR DESC) as 序號
FROM RowDataWReport
WHERE MWeight<>'0' AND YM >= '20170420' AND MItem='HJ03'
再來,同樣對表二做日期格式的轉換(轉成一般的日期格式,目前為字串),以及選出在當下的時間點生產的重量,
SELECT W.MItem AS 機器, (substring (W.YM,1,4)+'-'+substring(W.YM,5,2)+'-'+substring(W.YM,7,2)+' '+substring (W.HR,1,2)+':'+substring(W.HR,3,2)+':'+substring(W.HR,5,2)) as 時間 ,
W.MWeight AS 實際重量
FROM RowDataWReport W
WHERE MItem='HJ03' and YM='20170420'
接著,針對表二做機器資料的選取,
SELECT machname as 機器,article as 名稱,BeSpec as 規格,status as 生產狀態,cast(cast(RefWt as decimal(10,3))*1000 as decimal(10,1)) as 基礎重量,
convert (decimal (10,2),RefHiPcntWt) as 上限值, convert (decimal (10,2),RefLowPcntWt) as 下限值
FROM ProdStatus
有了上述的表格資訊後,接下來就是要整合在一起,並利用當中的資訊算出管制率(MAverageP)、
機器生產的狀況(介於上限值與下限值之間,105~100),
這時候就可使用 WITH AS() 的子查詢方式來做,完整的 SQL 如下:
With A as
(
SELECT MItem , YM , HR , ROW_NUMBER() OVER(PARTITION BY MItem ORDER BY YM DESC,HR DESC) as RK
FROM RowDataWReport
WHERE MWeight<>'0' AND YM >= '20170420' AND MItem='HJ03'
),
B AS
(
W.MItem, (substring (W.YM,1,4)+'-'+substring(W.YM,5,2)+'-'+substring(W.YM,7,2)+' '+substring (W.HR,1,2)+':'+substring(W.HR,3,2)+':'+substring(W.HR,5,2)) as DateTime ,
W.MWeight FROM RowDataWReport W
JOIN A ON W.Mitem = A.MItem and W.YM = A.YM and W.HR = A.HR and A.RK = 1
),
C AS
(
SELECT machname,article,BeSpec,status,cast(cast(RefWt as decimal(10,3))*1000 as decimal(10,1)) as StdWeight,
convert (decimal (10,2),RefHiPcntWt) as RefHiPcntWt, convert (decimal (10,2),RefLowPcntWt) as RefLowPcntWt
FROM ProdStatus
)
SELECT Machname, article, BeSpec, StdWeight as RefHiWt, MWeight as RefLowWt, WCR as MAverageP, RefHiPcntWt, RefLowPcntWt,
case when WCR between 100 and 105 then '正常'
else '異常 'end as ProdStatus , status
FROM
(
SELECT B.*,C.*,
(select cast((B.MWeight-C.StdWeight)*100/C.StdWeight+105 as decimal (10,2))) as WCR
FROM STD
LEFT JOIN B ON C.Machname = B.MItem
) R
ORDER BY machname
結果如下:
ROWNUMBER() OVER 的介紹,參考:
https://dotblogs.com.tw/joysdw12/2011/12/28/63596
WITH AS () 子查詢方法參考:
https://dotblogs.com.tw/dc690216/2010/02/02/13440