SQL составной ключ с личностью - PullRequest
2 голосов
/ 24 июня 2009

Возможно ли создать составной ключ в sql 2000 вида:

event_id id2
АДФ 1
АДФ 2
АДФ 3
CFG 1
CFG 2
edf 1

где id2 перезапускает счетчик при каждом изменении event_id. Мне нужно, чтобы нумерация была точно такой же, либо путем создания таблицы, либо с помощью другого трюка с оператором SELECT.

Edit: Возможно, я не был уверен, что мне нужна эта таблица только для объединения.

Ответы [ 5 ]

2 голосов
/ 24 июня 2009

Я бы не стал называть это тождеством, так как это не так и могло бы сбить с толку большинство других.

Я бы подумал, что вам придется сделать это с помощью триггера вставки и блокировки транзакции при увеличении последовательности.

0 голосов
/ 02 июля 2009

Это ответ, который я дал другому постеру, но он демонстрирует именно то, о чем вы просите:

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 для каждой группы!

Если вы собираетесь использовать результаты выбора более двух раз, то во время создания добавьте еще один столбец int во временную таблицу и обновите его новыми числами вместо того, чтобы вычислять его каждый раз. Я думаю о том, когда производительность будет лучше, чтобы сделать обновление ... тестирование в порядке.

0 голосов
/ 24 июня 2009

вроде как:

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
0 голосов
/ 24 июня 2009

Вы можете сделать это, используя триггер 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);
0 голосов
/ 24 июня 2009

Вы не можете заставить SQL делать это автоматически.

Если вам это действительно не нужно, пропустите его, вам нужно запросить таблицу, чтобы получить следующее значение, затем вставить строку, при этом блокируя выборки, чтобы никто другой не запросил, чтобы получить то же следующий.

Я бы назвал это SEQuence, а не ID, однако у вас будет лучше PK с обычным идентификатором, и вы все равно можете иметь столбец SEQ.

...