2016-12-08 100 views
1

新條目數系列目前還有一些數據,如生成基於現有的數據

+-------+-----+----------+ 
| House | Pet | ItemCode | 
+-------+-----+----------+ 
| A  | Cat | ACat001 | 
| A  | Dog | ADog001 | 
| B  | Cat | BCat001 | 
| A  | Dog | ADog002 | 
+-------+-----+----------+ 

我要生成的T-SQL新項目新項目的代碼一樣

+-------+-----+----------+--------------------------------+ 
| House | Pet | ItemCode | ItemCodes supposed to generate | 
+-------+-----+----------+--------------------------------+ 
| A  | Cat | ????  | ACat002      | 
| C  | Dog | ????  | CDog001      | 
+-------+-----+----------+--------------------------------+ 

請幫助。

+1

什麼是對這個結果的邏輯是什麼? – FLICKER

+0

誰投了這個問題,至少可以請讓我們知道預期的邏輯需要這個輸出! –

+0

用戶想要構建一個邏輯,以基於房屋和寵物爲新插入的數據生成新的物料代碼。因此A屋內新插入的貓將擁有一個ACat002項目代碼作爲房子A中的貓已經存在。 – ughai

回答

1

我會建議讓另一列作爲Index,從而打破項目代碼HousePetIndex,並創建從這些itemcode,也有標識列作爲表的主鍵這將使得該解決方案性能更簡單,更好。

考慮到表格是這樣的,你可以首先得到每個寵物在房子裏的最大指數,然後用它來計算下一個指數並更新itemcode爲新插入的數據。

表腳本和插入

CREATE TABLE HousePet 
    ([House] varchar(1), [Pet] varchar(3), [ItemCode] varchar(7)); 

INSERT INTO HousePet 
    ([House], [Pet], [ItemCode]) 
VALUES 
    ('A', 'Cat', 'ACat001'), 
    ('A', 'Dog', 'ADog001'), 
    ('B', 'Cat', 'BCat001'), 
    ('A', 'Dog', 'ADog002'); 

-- new rows inserted for which `ItemCode` is required 
INSERT INTO HousePet 
    ([House], [Pet], [ItemCode]) 
    VALUES 
    ('A', 'Cat', NULL), 
    ('C', 'Dog', NULL); 

更新SQL

;WITH HousePetIndex AS 
(
    SELECT House,Pet,MAX(CONVERT(INT,REPLACE(ItemCode,House + Pet,''))) as MaxIndex 
    FROM HousePet 
    WHERE ItemCode IS NOT NULL 
    GROUP BY House,Pet 
), HousePetInserted as 
(
    SELECT HP.House,HP.Pet,HP.ItemCode,ROW_NUMBER()OVER(PARTITION BY HP.House,HP.Pet ORDER BY HP.House) as ItemIndex 
    FROM HousePet HP 
    WHERE ItemCode IS NULL 
) 
UPDATE HP1 
SET ItemCode = HP1.House + HP1.Pet + RIGHT('000'+ CONVERT(VARCHAR(2),ItemIndex + ISNULL(HP2.MaxIndex,0)),3) 
FROM HousePetInserted HP1 
LEFT JOIN HousePetIndex HP2 
    ON HP1.House = HP2.House AND HP1.Pet = HP2.Pet 

SELECT * FROM HousePet 

邏輯

  • 獲取每家現有數據的索引最大和寵物在HousePetIndex CTE
  • 確定與在相同的寵物和房子的情況下多行基於row_number一些指標插入
  • 更新itemcode新行基於HousePetIndex從最高指數和指數衍生新行或新行

輸出

House Pet ItemCode 
A Cat ACat001 
A Dog ADog001 
B Cat BCat001 
A Dog ADog002 
A Cat ACat002 
C Dog CDog001 

編輯

如果你決定增加一個itemindex和標識列ID,可以使ItemCode作爲計算列。

CREATE TABLE HousePet 
(
    ID INT IDENTITY(1,1) PRIMARY KEY, 
    [House] varchar(1), 
    [Pet] varchar(3), 
    [ItemIndex] INT, 
    [ItemCode] AS (House + Pet + RIGHT('000'+ CONVERT(VARCHAR(2),ItemIndex),3)) 
); 

你可以做這樣的事情

UPDATE T 
SET ItemIndex = rn + MaxIndex 
FROM 
(
    SELECT ID,House,Pet,ItemIndex,ROW_NUMBER()OVER(PARTITION BY House,Pet ORDER BY ID ASC) rn 
    FROM HousePet 
    WHERE ItemIndex IS NULL 
)T 
INNER JOIN 
(
    SELECT House,Pet,ISNULL(MAX(ItemIndex),0) as MaxIndex 
    FROM HousePet 
    GROUP BY House,Pet 
) MaxIndexTable 
ON MaxIndexTable.House = T.House AND MaxIndexTable.Pet = T.Pet 
+0

感謝解決方案。所以,新表應該是4列House,Pet,Index和ItemCode(PrimaryKey),對嗎? –

+0

你的主鍵應該是一個單獨的'ID'列,最好是'IDENTITY'列。如果你真的想像這樣創建一個表,那麼你的'ItemCode'列就可以是一個基於'House','Pet','Index'的計算列,並且你只需要'更新''index'案件。 – ughai

+0

我明白了。謝謝。 –