我有像
这样的现有数据+-------+-----+----------+
| 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 |
+-------+-----+----------+--------------------------------+
请帮忙。
答案 0 :(得分:1)
我建议将另一列保留为Index
,以便在House
,Pet
和Index
中破解项目代码,并从中创建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
,House
和Pet
更新新行的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