根据现有数据为新条目生成数字序列

时间:2016-12-08 07:32:16

标签: sql tsql

我有像

这样的现有数据
+-------+-----+----------+
| 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 个答案:

答案 0 :(得分: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识别包含某些索引的新行
  • 根据源自最大索引和索引或新行的itemcodeHousePet更新新行的Index

<强>输出

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