iT邦幫忙

0

請教SQL,如何取出每一筆出庫之對應(最近)前次的的進貨日

sql

若我有一個-庫存進出明細 (如附圖之上半部格式資料)

接下來用SQL取出最近出庫的明細
select * from 庫存進出 where 進出='出'

接下來該如何下SQL把其後帶出,每一筆出庫之對應(最近)前次的的進貨日如附圖(紅色處)

看更多先前的討論...收起先前的討論...
我覺得應該是用 Correlated Subquery 來查詢
不過我手邊沒環境
也寫不出 SQL
臉紅
期待其他高手出手
簽名
Albert iT邦高手 1 級 ‧ 2013-03-25 23:38:20 檢舉
hisniper iT邦新手 2 級 ‧ 2013-03-25 23:50:03 檢舉
用Correlated Subquery
有寫出對應品號之最後一次進貨日

但寫不出前一次進貨日
頭腦卡住了.
Albert iT邦高手 1 級 ‧ 2013-03-25 23:55:05 檢舉
說這是[模擬耗用]
有些學生會生氣
這跟在研究所指導學生專案時
學生聽不懂
被學生罵為什麼講他聽不懂的話!!
(這我有被罵的經驗)
.....
以後到60級分後的學校, 要小心講解以免被罵...
.....
還好在 [台灣最大電腦製造公司] 他們都聽懂 ASCP[MCATP] 模擬耗用
還好在 [全球最大資訊服務公司] 他們都聽懂 ASCP[MCATP] 模擬耗用
........
那應該不是我講得很離譜
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
4
dscwferp
iT邦高手 1 級 ‧ 2013-03-26 08:49:45
最佳解答

如果是 MSSQL 可以用如下指令:

<pre class="c" name="code">SELECT     品號, 進出, 數量, 日期, MAX(B.日期) AS 前次進貨日
FROM         庫存進出 AS A LEFT OUTER JOIN
                      庫存進出 AS B ON A.品號 = B.品號 AND A.日期 > B.日期
WHERE     (B.進出 = 1) AND (A.進出 = - 1)
GROUP BY A.品號, A.進出, A.數量, A.日期

純推不懂
汗

6
Albert
iT邦高手 1 級 ‧ 2013-03-25 21:36:17

如果這樣 [湊] 就為了 [財務會計] 評價的問題

倒算出 [庫存] 是怎麼來的...

如果 [批量控管] 出貨單會有 [原進貨單號]

就不是這樣寫...

我們用 procedure 的 cursor loop
將 [進貨]
一個一個分配給 [出貨]
紀錄下 [出貨用了哪一個進貨]
[引][興]好像沒有模擬[耗用]

call me ,
Skype: Adempiere/Compiere
Albert

看更多先前的回應...收起先前的回應...
hisniper iT邦新手 2 級 ‧ 2013-03-25 22:45:08 檢舉

請不要回答出沒關係的答案.
由其拉出公司別,實在很不好.
我也不是在那家公司!!

本題目只是要求SQL語法
題目只是舉例,這樣比較好讓人寫出解答.
這真的是很糟糕的回答
請原諒我的直言.

Albert iT邦高手 1 級 ‧ 2013-03-25 23:29:25 檢舉

你太聰明
連這個答案你也看不懂
無法配服你更多了
你的回答很棒

hisniper提到:
請不要回答出沒關係的答案.

別在意
是你太久沒來這裡了

Albertachen大大的每一個答案
都是這麼讓人摸不著頭緒的
暈

ted99tw iT邦高手 1 級 ‧ 2013-03-26 10:52:23 檢舉

阿伯有給答案嗎?暈

總裁 iT邦好手 1 級 ‧ 2013-03-26 11:01:15 檢舉

albertachen提到:
call me

睡覺

鐵殼心 iT邦高手 1 級 ‧ 2013-03-26 11:10:43 檢舉

ted99tw提到:
阿伯有給答案嗎?

請面洽阿伯

call me ,
Skype: Adempiere/Compiere
Albert

6
kissingboy
iT邦新手 4 級 ‧ 2013-03-26 09:40:56

參考看看

<pre class="c" name="code">
--MSSQL
--建資料
Declare @tmp Table
(
	[item] nvarchar(60),
	[type] nvarchar(60),
	[qty]  numeric(9,0),
	[date] date
)

INSERT INTO @tmp VALUES('A','IN',1,'2013/01/01')
INSERT INTO @tmp VALUES('A','OUT',-1,'2013/01/02')
INSERT INTO @tmp VALUES('A','IN',1,'2013/01/03')
INSERT INTO @tmp VALUES('A','OUT',-1,'2013/01/04')
INSERT INTO @tmp VALUES('B','IN',2,'2013/01/01')
INSERT INTO @tmp VALUES('B','OUT',-1,'2013/01/02')
INSERT INTO @tmp VALUES('B','OUT',-1,'2013/01/03')
INSERT INTO @tmp VALUES('C','IN',1,'2013/01/01')
INSERT INTO @tmp VALUES('C','IN',1,'2013/01/02')
INSERT INTO @tmp VALUES('C','OUT',-1,'2013/01/03')
INSERT INTO @tmp VALUES('C','IN',1,'2013/01/04')


;WITH Data_List AS(
	SELECT a.*,b.date as out_date
		FROM @tmp a
		LEFT JOIN @tmp b on a.item =b.item and b.type = 'IN'
		WHERE a.type = 'OUT'
		AND DATEDIFF(D,a.date,b.date) < 0
)

SELECT item ,type ,qty ,date ,out_date
	FROM (
			SELECT MAX(out_date) OVER (PARTITION BY item ,date) AS SN,*
				FROM Data_List
	) tmp
	WHERE SN = out_date

純推不懂
汗

外獅佬 iT邦大師 1 級 ‧ 2013-03-26 10:39:41 檢舉

用CTE....不錯不錯...但是...資料庫如果不是MSSQL....汗

Albert iT邦高手 1 級 ‧ 2013-03-27 09:46:11 檢舉

SELECT MAX(out_date) OVER (PARTITION BY item ,date) AS SN,*
FROM Data_List

這是 [新進員工] 的寫作方式
最好不要這樣
否則[全球最大資訊服務業]可以會讓你去再教育

4
summertw
iT邦好手 1 級 ‧ 2013-03-26 10:33:17

要的資料是本次的出貨記錄及前一次的出貨數量記錄..
建議使用標準SQL-92語法中的子查詢..
目的:1.可避免前一次無出貨的NULL請況,致本次資料無法輸出。
目的:2.不使用Join方式,以簡化程式的可看性。
程式飯粒:
SELECT item ,
type ,
qty ,
date ,
out_date ,
(Select Top 1 b.qty From FocusTableName b
Where b.item = a.item
And b.out_date < (Select MAX(c.out_date) From FocusTableName c
Where c.item = a.item)
Order By b.out_date Desc) AS Pre_qty
From FocusTableName
Where FocusTableName.type = 'OUT'
And FocusTableName.out_date = (Select MAX(D.out_date) From FocusTableName D
Where D.item = FocusTableName.item)

純推不懂
汗

4
pojen
iT邦研究生 5 級 ‧ 2013-03-26 11:27:07

很有趣的問題, 如果資料不大的話可以把資料重新排序一下就可以了.

測試

準備

不怎麼好看的 SQL

如果只要出貨的部份, 那就讓第二次的 ecategory 不是 null 就好.

純推不懂
汗
越寫越誇張了
暈

ted99tw iT邦高手 1 級 ‧ 2013-03-26 11:46:01 檢舉

好厲害喔,再加油一下就成一個app了...汗

10
一級屠豬士
iT邦大師 1 級 ‧ 2013-03-26 15:40:47
&lt;pre class="c" name="code">
使用MySQL, 日期欄位修正為日期格式.
CREATE TABLE ithelp0326(
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
partno CHAR(1) NOT NULL,
tran CHAR(2) NOT NULL,
qty INT NOT NULL,
mdate DATE NOT NULL
);

INSERT INTO ithelp0326(partno, tran, qty, mdate) VALUES
('A', '進', 1, '2013-1-1'),
('A', '出', -1, '2013-1-2'),
('A', '進', 1, '2013-1-3'),
('A', '出', -1, '2013-1-4'),
('B', '進', 2, '2013-1-1'),
('B', '出', -1, '2013-1-2'),
('B', '出', -1, '2013-1-3'),
('C', '進', 1, '2013-1-1'),
('C', '進', 1, '2013-1-2'),
('C', '出', -1, '2013-1-3'),
('C', '進', 1, '2013-1-4');

SELECT a.partno, a.tran, a.qty, a.mdate, MAX(b.mdate) AS '前次進貨日'
FROM ithelp0326 a
LEFT JOIN ithelp0326 b
ON a.partno = b.partno
AND a.mdate > b.mdate
WHERE a.tran = '出' 
AND b.tran = '進'
GROUP BY a.partno, a.mdate
ORDER BY a.partno, a.mdate;

結果如圖:

看更多先前的回應...收起先前的回應...

果然厲害厲害
拍手拍手

ted99tw iT邦高手 1 級 ‧ 2013-03-26 15:56:42 檢舉

純推不懂 汗

Albert iT邦高手 1 級 ‧ 2013-03-26 18:23:10 檢舉

MAX(b.mdate) AS '前次進貨日'
FROM ithelp0326 a
LEFT JOIN ithelp0326 b ON a.partno = b.partno AND a.mdate > b.mdate

如果這樣寫只抓 :
同料號(partno)
出貨之前 a.mdate > b.mdate
最近一次 max(b.mdate)
...
剛剛那群...上海交大學生...就會了
...

Albert iT邦高手 1 級 ‧ 2013-03-27 16:28:26 檢舉

ted99tw提到:
純推不懂

純懂 不推 ?

推懂 不純 ?

總裁 iT邦好手 1 級 ‧ 2013-03-27 17:01:02 檢舉

懂不??純推!!毆飛

2
obiwanking
iT邦新手 3 級 ‧ 2013-03-27 10:25:19

albertachen提到:
如果這樣寫只抓 :
同料號(partno)
出貨之前 a.mdate > b.mdate
最近一次 max(b.mdate)

如果只是語法的問題, hitomitanaka 的回答已經解決, 而且解得蠻漂亮的.
但是實務上, 我覺得這樣的資料結構應該會有很大的問題(效能).

比較洽當的方式應該是針對不同工廠, 品號之間的鋪貨table會去紀錄最近一次的進貨日期.
當你在撈取出貨明細時, 直接join 鋪貨的table即可馬上抓取最後一次進貨日.
避免資料庫過多的運算
這點在資料筆數很多時, 差異會很明顯.
用一點空間(多一個欄位)換取, 很划算的.

看更多先前的回應...收起先前的回應...

如果系統架構沒有鋪貨的table, 也可設計在即時庫存的table中

設計出好的架構需要許多經驗與切合實務上需求.
若是我的話,不會產生這種 "每一筆品項的出貨日期去查 最近進貨日期", 還一一列出來; 實務上品項會很多,即使是小公司少說也幾百,人類去一一看,也沒多大用處;
還不如去找出,最大差距,平均差距,或是每隔10天的數量累積等等; 再來就是依據供應廠商,產品大類,客戶等,再把剛剛的最大差距等等分別計算出來,會比單一項列出來,有意思多了.

Albert iT邦高手 1 級 ‧ 2013-03-27 11:03:41 檢舉

模擬 [領用] 不是這樣寫
因為 [反核] 看到核桃就 [暈倒]

不是抓最後一筆

http://ithelp.ithome.com.tw/upload/images/20130327/2013032711032851526180e793f_thumb.jpg

Albert iT邦高手 1 級 ‧ 2013-03-27 11:04:09 檢舉
Albert iT邦高手 1 級 ‧ 2013-03-27 11:19:54 檢舉

老大啊,你要賣東西,請先抽號碼牌吧.

Albert iT邦高手 1 級 ‧ 2013-03-27 13:36:26 檢舉

寫不出來 又不是只有讀 [中段][後段]大學的權利

中國最大手機製造工廠有一堆 北大清大交大一樣沒有做出來

需要有 well-tranning 又有豐富經驗的 才可以做出來

ASCP / MCATP 先進棑程
Demand / Supply 模擬
技術轉移顧問
Skype: Adempiere/Compiere
Albert

Albert iT邦高手 1 級 ‧ 2013-03-27 15:44:50 檢舉

我要發表回答

立即登入回答