是否可以在以下格式的sql 2000中创建复合键:
event_id id2
adf 1
adf 2
adf 3
cfg 1
cfg 2
edf 1
其中id2在每次更改event_id时重新开始计数。我需要通过创建表或其他SELECT语句技巧来使编号完全相同。
编辑: 我可能不太清楚我只是暂时需要这个表来加入。
答案 0 :(得分:2)
我会避免称这是一个身份,因为它不会,并且会让大多数人感到困惑。
我认为你必须通过插入触发器和事件锁定来完成这个过程。
答案 1 :(得分:0)
您无法让SQL自动为您执行此操作。
如果你真的不需要这个,那么跳过它,你需要查询表以获取下一个值然后必须插入行,同时锁定选择,所以没有其他人查询得到相同的下一个。
我称之为SEQuence而不是ID,但是你只有一个更好的PK,只有一个普通的身份,你仍然可以有一个SEQ列。
答案 2 :(得分:0)
您可以使用INSTEAD OF触发器执行此操作。我认为你可以在一次插入一行的情况下使用它,但我想不出为多行插入执行它的方法,因为SQL 2000没有ROW_NUMBER()函数。
我认为您最好的方法是使用存储过程。类似的东西:
CREATE PROC insert_event(@event_id char(3)) AS
DECLARE @max int;
SELECT @max = MAX(identity) WHERE event_id = @event_id;
INSERT INTO [table] (event_id, identity) VALUES (@event_id, @max + 1);
答案 3 :(得分:0)
这是我给另一张海报的答案,但它确切地证明了你的要求:
SELECT
seqid = identity(int, 1, 1),
event_id,
S.name
INTO #EventNames
FROM
celcat200809.dbo.CT_EVENT_STAFF ES
LEFT JOIN celcat200809.dbo.CT_STAFF S ON ES.staff_id = S.staff_id
ORDER BY
event_id,
S.name
SELECT
EN.event_id,
Max(CASE seqid - minseqid WHEN 0 THEN EN.name ELSE '' END))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 1 THEN EN.name ELSE NULL END, ''))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 2 THEN EN.name ELSE NULL END, ''))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 3 THEN EN.name ELSE NULL END, ''))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 4 THEN EN.name ELSE NULL END, ''))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 5 THEN EN.name ELSE NULL END, ''))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 6 THEN EN.name ELSE NULL END, ''))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 7 THEN EN.name ELSE NULL END, ''))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 8 THEN EN.name ELSE NULL END, ''))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 9 THEN EN.name ELSE NULL END, ''))
+ Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 10 THEN EN.name ELSE NULL END, ''))
FROM
#EventNames EN
INNER JOIN (
SELECT event_id, minseqid = Min(seqid) FROM #EventNames GROUP BY event_id
) X ON EN.event_id = X.event_id
GROUP BY EN.event_id
您可以忽略10个Max()表达式。关键部分是: - 将值粘贴到带有标识列的临时表中,按组按顺序排序。 - 使用聚合查询获取每组的最小值(上面派生的表X) - 从身份值中减去最小值(如果需要从1开始编号,则加1)并且每个组的数字重新开始为1!
如果您要使用select两次以上的结果,那么在创建时将另一个int列添加到临时表并使用新数字更新它,而不是每次都计算它。我猜测性能何时更好地进行更新...测试是有序的。
答案 4 :(得分:-1)
有点像这样:
CREATE TABLE #Temp (val char(3))
INSERT INTO #Temp VALUES ('adf')
INSERT INTO #Temp VALUES ('adf')
INSERT INTO #Temp VALUES ('adf')
INSERT INTO #Temp VALUES ('cfg')
INSERT INTO #Temp VALUES ('cfg')
INSERT INTO #Temp VALUES ('edf')
SELECT
Val,
ROW_NUMBER() OVER (PARTITION BY Val ORDER BY Val)
FROM #Temp
DROP TABLE #Temp