我正在将一堆代码从完全基于光标的基础上移动到基于集合并生成这一直在我的脑袋里。我们为插入数据库的每个公司创建一个6字符的短代码(唯一),我想要在游标之外实现这一点。
到目前为止我所处的位置示例:
CREATE TABLE #customers (name VARCHAR(50), shortname VARCHAR(10))
INSERT INTO #customers VALUES
('Michael Smith', 'Michae')
,('Michael Douglas', 'Mich_1')
,('Michael Yang', 'Mich_2')
CREATE TABLE #newcustomers (name VARCHAR(50), shortname VARCHAR(10) NULL)
INSERT INTO #newcustomers (name) VALUES
('Michael Black')
,('Michael White')
SELECT * FROM #customers
SELECT * FROM #newcustomers
DECLARE @shortname VARCHAR(10)
DECLARE @iteration INT = 0
WHILE EXISTS(SELECT shortname FROM #customers WHERE shortname = @shortname)
BEGIN
SELECT @shortname = LEFT(name, 6) FROM #newcustomers
UPDATE #newcustomers SET shortname = @shortname
SET @shortname = LEFT(@shortname, 4) + '_' + @iteration
SET @iteration = @iteration + 1
END
希望这个例子足以确定我想要去的地方,任何建议或例子都会非常有用。我的例子不起作用。
答案 0 :(得分:2)
试试这个
您的桌子为模拟
CREATE TABLE #customers (ID INT IDENTITY, name VARCHAR(50), shortname VARCHAR(10))
INSERT INTO #customers VALUES
('Michael Smith', 'Michae')
,('Michael Douglas', 'Mich_1')
,('Michael Yang', 'Mich_3')
,('Testman', 'Testma')
,('Testman1', 'Test_1');
CREATE TABLE #newcustomers (ID INT IDENTITY,name VARCHAR(50), shortname VARCHAR(10) NULL)
INSERT INTO #newcustomers (name) VALUES
('Michael Black')
,('Michael White')
,('Testman2')
,('Someone new');
- 此CTE将结合所有现有名称
WITH AllNames AS
(
SELECT '1_old' AS datasource,ID,name,shortname FROM #customers
UNION ALL SELECT '2_new',ID,name,shortname FROM #newcustomers
)
- 此CTE将使用组合列表并计算正确的“索引”
,ShortNames AS
(
SELECT c.*
,A.First6
,ROW_NUMBER() OVER(PARTITION BY A.First6 ORDER BY datasource,ID) AS NrTotal
,ROW_NUMBER() OVER(PARTITION BY datasource,A.First6 ORDER BY datasource,ID) AS Nr
,CASE WHEN ISNUMERIC(SUBSTRING(shortname+' ',6,10))=1
THEN CAST(SUBSTRING(shortname+' ',6,10) AS INT) ELSE 0 END AS ExistIndex
FROM AllNames AS c
CROSS APPLY(SELECT LEFT(name + ' ',6)) AS A(First6)
)
- 所有新的NrTotal = 1得到6个字母,其他所有得到索引
SELECT *
,CASE WHEN datasource='1_old' THEN shortname ELSE
CASE WHEN datasource='2_new' AND NrTotal=1 THEN First6
ELSE LEFT(First6,4) + '_' + CAST(Nr + (SELECT ISNULL(MAX(x.ExistIndex),1)
FROM ShortNames AS x
WHERE x.First6=ShortNames.First6) AS VARCHAR(5))
END
END
FROM ShortNames
GO
DROP TABLE #customers;
DROP TABLE #newcustomers;
结果
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| datasource | ID | name | shortname | First6 | NrTotal | Nr | ExistIndex | (Kein Spaltenname) |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| 1_old | 1 | Michael Smith | Michae | Michae | 1 | 1 | 0 | Michae |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| 1_old | 2 | Michael Douglas | Mich_1 | Michae | 2 | 2 | 1 | Mich_1 |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| 1_old | 3 | Michael Yang | Mich_3 | Michae | 3 | 3 | 3 | Mich_3 |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| 1_old | 4 | Testman | Testma | Testma | 1 | 1 | 0 | Testma |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| 1_old | 5 | Testman1 | Test_1 | Testma | 2 | 2 | 1 | Test_1 |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| 2_new | 1 | Michael Black | NULL | Michae | 4 | 1 | 0 | Mich_4 |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| 2_new | 2 | Michael White | NULL | Michae | 5 | 2 | 0 | Mich_5 |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| 2_new | 4 | Someone new | NULL | Someon | 1 | 1 | 0 | Someon |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
| 2_new | 3 | Testman2 | NULL | Testma | 3 | 1 | 0 | Test_2 |
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+
答案 1 :(得分:0)
一种选择是使用computed column。
沿着这些方向的表格设计将起作用:
- Sample table.
DECLARE @Sample TABLE
(
Id INT IDENTITY(1, 1),
FullName VARCHAR(255),
ShortName AS LEFT(FullName, 4) + '_' + CAST(Id AS VARCHAR(255))
)
;
-- Add set containing two companies.
INSERT INTO @Sample
(
FullName
)
VALUES
('ABC LTD'),
('XYZ PLC')
;
返回
Id FullName ShortName
1 ABC LTD ABC _1
2 XYZ PLC XYZ _1
Id
和ShortName
列将由SQL Server管理。您只需要添加FullName
。
修改强>
使用表变量重写示例,以便更轻松地进行播放。