先訂清楚要判斷甚麼,再準備資料
同一張訂單可能有一項已送齊,另一項只送了一部分。先逐項合計已完成送貨,再減訂購數量。待處理送貨還未完成,不能先扣欠貨數。明細層面的清單才方便出貨同事沿貨品跟進,單看訂單表頭容易漏掉部分欠貨。
以下全部是假設資料。請在新的 SQLite 測試資料庫建立各表,再執行唯讀查詢。數量以件計,金額以港元的分作整數儲存;顯示港元時除以 100。
| 編號 | 訂單編號 | 貨品編號 | 訂購數量 | 單價(分) |
|---|---|---|---|---|
| L1 | O1 | A | 5 | 1000 |
| L2 | O1 | B | 3 | 2000 |
| L3 | O2 | C | 4 | 500 |
| L4 | O3 | A | 1 | 1000 |
CREATE TABLE orders(id TEXT PRIMARY KEY, status TEXT);
CREATE TABLE order_lines(id TEXT PRIMARY KEY, order_id TEXT, sku TEXT, ordered_qty INTEGER, unit_cents INTEGER);
CREATE TABLE deliveries(id TEXT PRIMARY KEY, line_id TEXT, qty INTEGER, status TEXT);
CREATE TABLE billed_lines(id TEXT PRIMARY KEY, line_id TEXT, qty INTEGER, status TEXT);
INSERT INTO orders VALUES ('O1','confirmed'),('O2','confirmed'),('O3','cancelled');
INSERT INTO order_lines VALUES ('L1','O1','A',5,1000),('L2','O1','B',3,2000),('L3','O2','C',4,500),('L4','O3','A',1,1000);
INSERT INTO deliveries VALUES ('D1','L1',2,'completed'),('D2','L1',2,'completed'),('D3','L2',3,'completed'),('D4','L3',1,'pending'),('D5','L4',1,'completed');
INSERT INTO billed_lines VALUES ('BL1','L1',2,'issued'),('BL2','L2',3,'issued'),('BL3','L1',1,'void');執行查詢,核對實際結果
WITH shipped AS (
SELECT line_id,SUM(qty) AS qty FROM deliveries WHERE status='completed' GROUP BY line_id
)
SELECT l.order_id,l.id AS line_id,l.ordered_qty,COALESCE(s.qty,0) AS delivered_qty,
l.ordered_qty-COALESCE(s.qty,0) AS remaining_qty
FROM order_lines l JOIN orders o ON o.id=l.order_id
LEFT JOIN shipped s ON s.line_id=l.id
WHERE o.status='confirmed' AND COALESCE(s.qty,0)<l.ordered_qty
ORDER BY l.order_id,l.id;| 訂單編號 | 明細編號 | 訂購數量 | 已送數量 | 尚欠數量 |
|---|---|---|---|---|
| O1 | L1 | 5 | 4 | 1 |
| O2 | L3 | 4 | 0 | 4 |
O1 的 L1 尚欠 1 件,L2 已送齊;O2 的 L3 仍欠 4 件,因為那筆 1 件送貨未完成;O3 已取消,所以不列入。答應出貨日期前,要再與可用存量比較。
按資料範圍使用結果
例子未包括取消欠貨、替代貨品、退回送貨或批准多送。這些情況須有正負數量事件及另外查核。清單沒有結果,只代表按這套規則沒有欠貨,不代表每張訂單都正確。
本例的建表、資料及結果已在 SQLite 執行。套用時先在系統測試副本調整欄位及狀態規則,再與流程負責人核對預期結果。其他資料庫平台未經測試。