iT邦幫忙

0

如何使用T-SQL查詢主料與替代料的關係

  • 分享至 

  • xImage

您好:
目前資料的結構如下示:
https://ithelp.ithome.com.tw/upload/images/20220818/20086882XGBBO2Ilbh.jpg

ITEM_SR只是各料輸入的順序,主料與替代料的關連方式為:
當C_SBS為N時的下一筆C_SBS為Y的情況下,這筆C_SBS為N的料是主料,
C_SBS為Y的料是替代料,一直遇到下一筆C_SBS為N的時候停止主料與替代
料的關係。

因此期待查詢的結果如下示:
https://ithelp.ithome.com.tw/upload/images/20220819/20086882wBOSFqvxNv.jpg

還請各位高手協助如果不在AP端解決的情況下,是否可以使用SQL來達成這樣的查詢,
謝謝您。

froce iT邦大師 1 級 ‧ 2022-08-19 09:01:47 檢舉
> 當C_SBS為N時的下一筆C_SBS為Y的情況下,這筆C_SBS為N的料是主料,
C_SBS為Y的料是替代料,一直遇到下一筆C_SBS為N的時候停止主料與替代
料的關係。

設計這個資料庫的人...
正常來說會有另外一個表寫好主從關係
簡單說就是你想要得到結果的那個表應該是要手動KEY的,不然你任何一個主料要新增替代料會變得很麻煩,因為你用循序報表來做索引,這樣會很難下手
v855617 iT邦新手 4 級 ‧ 2022-08-22 17:34:55 檢舉
公司購買套裝軟體,當初還沒有替代料的部份。後來有詢問替代料部份的需求,才變成了以上下關係來表示替代料。
這樣設計的好處,嗯 .......省了資料表要另外設計。但是後需使用者需求要查替代料就很 麻煩了,沒有介面可以去查。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
水無痕
iT邦新手 3 級 ‧ 2022-08-20 09:19:28
最佳解答
DECLARE @Test TABLE
              (
                  [ITEM_SR]    INT,
                  [CP_ITEM_NO] NVARCHAR(20) NULL,
                  [C_SBS]      NVARCHAR(20) NULL -- N:主料代  Y:替代料
              );

INSERT INTO @Test ([ITEM_SR], [CP_ITEM_NO], [C_SBS])
VALUES (10, 'A0001', 'N'),
       (11, 'B0001', 'Y'),
       (12, 'C0001', 'Y'),
       (20, 'D0001', 'N'),
       (30, 'E0001', 'Y'),
       (40, 'F0001', 'Y'),
       (50, 'G0001', 'N'),
       (51, 'H0001', 'N'),
       (61, 'I0001', 'N'),
       (70, 'J0001', 'N'),
       (71, 'K0001', 'Y'),
       (72, 'L0001', 'N');

WITH [BASE] AS (SELECT *
                FROM @Test
                WHERE [C_SBS] = 'N'
               ),
     [SBS] AS (SELECT *
               FROM @Test
               WHERE [C_SBS] = 'Y'
              )
SELECT [BASE2].[CP_ITEM_NO] AS [BASE_CP_ITEM_NO],
       [SBS].[CP_ITEM_NO]   AS [SBS_CP_ITEM_NO]
FROM [SBS]
    OUTER APPLY (SELECT TOP 1 *
                 FROM [BASE]
                 WHERE [SBS].[ITEM_SR] > [ITEM_SR]
                 ORDER BY [ITEM_SR] DESC
                ) [BASE2]

https://ithelp.ithome.com.tw/upload/images/20220820/20137005wJR6rkp3ld.png

v855617 iT邦新手 4 級 ‧ 2022-08-26 11:19:25 檢舉

謝謝您,這樣寫法很適合舊版Server上,不需要用到LEAD函數。
也讓我自己豁然開朗,自己一直想成用if的方式來處理,其實只要順序對了就可以用比對序號的方式處理。

2
rogeryao
iT邦超人 8 級 ‧ 2022-08-19 06:16:54
CREATE TABLE TEST (
ITEM_SR	INT,
CP_ITEM_NO NVARCHAR(20) NULL,	
C_SBS NVARCHAR(20) NULL);

INSERT INTO TEST (ITEM_SR,CP_ITEM_NO,C_SBS) VALUES
(10,'A0001','N'),
(11,'B0001','Y'),
(12,'C0001','Y'),
(20,'D0001','N'),
(30,'E0001','Y'),
(40,'F0001','Y'),
(50,'G0001','N'),
(51,'H0001','N'),
(61,'I0001','N'),
(70,'J0001','N'),
(71,'K0001','Y'),
(72,'L0001','N'),
-- 額外加入
(110,'A0001','N'),
(111,'B0001','Y'),
(112,'C0001','Y'),
(210,'A0001','N'),
(211,'B0002','Y'),
(212,'C0002','Y');
WITH CTE_X1 AS (
SELECT ITEM_SR,CP_ITEM_NO,C_SBS
FROM TEST
),
CTE_X2 AS (
SELECT CP_ITEM_NO,ITEM_SR AS ITEM_SR_START,C_SBS,
LEAD(ITEM_SR, 1, (SELECT MAX(ISNULL(ITEM_SR,0)) + 1 FROM TEST))
OVER (ORDER BY ITEM_SR) AS ITEM_SR_END
FROM CTE_X1
WHERE C_SBS = 'N')

SELECT DISTINCT B.CP_ITEM_NO AS 'BASE_ITEM_NO',A.CP_ITEM_NO AS 'SBS_ITEM_NO'
FROM CTE_X1 AS A
LEFT JOIN CTE_X2 AS B ON A.ITEM_SR >= B.ITEM_SR_START AND A.ITEM_SR < B.ITEM_SR_END
WHERE A.CP_ITEM_NO <> B.CP_ITEM_NO
ORDER BY B.CP_ITEM_NO,A.CP_ITEM_NO

Demo

解法參考 :[SQL]歷史異動資料有生失效區間, 如何用善用PIVOT橫長
(欄位值 = NULL 時抓同群組的第一筆非 NULL 值填入)

【SQL Server 2008】未測

WITH CTE_01 AS (
SELECT CP_ITEM_NO,ITEM_SR,C_SBS,
CASE WHEN C_SBS = 'Y' THEN 0 ELSE 1 END AS NO_TEMP
FROM TEST
),
CTE_02 AS (
SELECT *,
(SELECT SUM(X.NO_TEMP) FROM CTE_01 AS X WHERE X.ITEM_SR <= A1.ITEM_SR) AS NO
FROM CTE_01 AS A1 
),
CTE_03 AS(
SELECT CP_ITEM_NO,ITEM_SR,C_SBS,ROW_NUMBER() OVER (ORDER BY ITEM_SR) AS NO
FROM TEST
WHERE C_SBS = 'N')

SELECT DISTINCT B.CP_ITEM_NO AS 'BASE_ITEM_NO',A2.CP_ITEM_NO AS 'SBS_ITEM_NO'
FROM CTE_02 AS A2
LEFT JOIN CTE_03 AS B ON B.NO = A2.NO
WHERE A2.CP_ITEM_NO <> B.CP_ITEM_NO
ORDER BY B.CP_ITEM_NO,A2.CP_ITEM_NO

Demo2

v855617 iT邦新手 4 級 ‧ 2022-08-22 17:38:25 檢舉

謝謝您,不過目前公司仍使用SQL Server 2008 R2,這樣就與LEAD函數無緣了。
目前正在參考改寫成在SQL Server 2008 R2上沒有LEAD函數的方式,正在努力中。

rogeryao iT邦超人 8 級 ‧ 2022-08-23 09:29:57 檢舉

【SQL Server 2008】未測,請自行測試。

0
海綿寶寶
iT邦大神 1 級 ‧ 2022-08-19 10:43:19

我不會
因為我不解其精妙之處

照這個設計概念
如果 A0001 要加一個替代料
大概會是

13 B0002 Y

如果再加 7 個替代料
不知道如何處理,因為 ITEM_SR 會變成

14,15,16,17,18,19 (20 已使用了)

大概最多不會有那麼多替代料吧
/images/emoticon/emoticon06.gif

rogeryao iT邦超人 8 級 ‧ 2022-08-19 16:44:58 檢舉

這個資料結構是很奇怪的,不過針對【如果 A0001 要加一個替代料】這個問題可以用我舉例的(-- 額外加入)
方式加入 A0001 多筆替代料,只是每次都要建 A0001 是主料件。
如果沒先建 A0001 是主料件,那就會對應錯誤。

v855617 iT邦新手 4 級 ‧ 2022-08-22 17:45:13 檢舉

他設計方式是A0001的C_SBS是Y時的上一筆C_SBS是N的料是主料,替代料有可能是會多一些,當RD完全沒有移掉作廢的料號時。
另外系統沒有自動選取替代料的做法,所以這樣設計時變成要自己手動去刪減替代料。

我要發表回答

立即登入回答