2016-12-08 99 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

我明白了。谢谢。 –