2014-10-20 2 views
-1

У меня есть стол с тремя колонками по имени cid, orderdate и priororderdate среди прочих.SQL: Создать новый столбец идентификатора, который изменяется в зависимости от значений других трех столбцов?

Вот как выглядит таблица:

cid orderdate   priororderdate    position 
12 NULL     NULL       1 
12 NULL     NULL       2 
12 NULL     NULL       3 
12 2014-08-08 23:25  NULL       1 
12 2014-08-08 23:25  NULL       2 
12 2014-08-08 23:25  NULL       3 
12 2014-08-08 23:25  NULL       4 
12 2014-09-06 17:19  2014-08-08 23:25    1 
12 2014-09-06 17:19  2014-08-08 23:25    2 
12 2014-09-06 17:19  2014-08-08 23:25    3 
13 NULL     NULL       1 
13 NULL     NULL       2 
13 NULL     NULL       3 

Сочетание колонн cid, orderdatetime и priororderdatetime определяет уникальный fpid (новый столбец, я хочу создать). Таким образом, конечный результат будет:

cid orderdate   priororderdate    position  fpid 
12 NULL     NULL       1   1 
12 NULL     NULL       2   1 
12 NULL     NULL       3   1 
12 2014-08-08 23:25  NULL       1   2 
12 2014-08-08 23:25  NULL       2   2 
12 2014-08-08 23:25  NULL       3   2 
12 2014-08-08 23:25  NULL       4   2 
12 2014-09-06 17:19  2014-08-08 23:25    1   3 
12 2014-09-06 17:19  2014-08-08 23:25    2   3 
12 2014-09-06 17:19  2014-08-08 23:25    3   3 
13 NULL     NULL       1   4 
13 NULL     NULL       2   4 
13 NULL     NULL       3   4 

Как я могу создать fpid колонку?

+0

Данные, которые вы показываете, показывают, что они не уникальны. Вы можете рассчитать значение с помощью триггера или в вашем программном коде и обеспечить уникальность уровня db с помощью уникального индекса. – NoChance

+1

Это звучит как проблема [XY] (http://meta.stackexchange.com/q/66377/135230), так как вы можете различать все строки, в которых первые три столбца одинаковы, используя 'GROUP BY'. Для чего вы собираетесь использовать 'fpid'? –

ответ

2

Вы можете сделать это с помощью dense_rank() в select запроса:

select t.*, 
     dense_rank() over (order by cid, orderdate, priororderdate) as fpid 
from table t; 

Если у вас есть столбец fpid уже в таблице и хотите обновить его:

with toupdate as (
     select t.*, 
      dense_rank() over (order by cid, orderdate, priororderdate) as new_fpid 
     from table t 
    ) 
update toupdate 
    set fpid = new_fpid; 

(если вы хотите добавить его, вы можете использовать заявление alter table.)

+0

Очень чистое и эффективное решение. Спасибо. – Georgia2004

1

Это немного путаница, что вы говорите, что fpid уникален, но, глядя на ваш желаемый результат, похоже, вы хотите использовать ROW_NUMBER().

UPDATE tab2 t SET fpid = 
(SELECT ROW_NUMBER() OVER (ORDER BY cid) 
FROM tab2 
GROUP BY cid, orderdate, priororderdate 
WHERE t.cid = cid 
AND t.orderdate = orderdate 
AND t.priororderdate = priororderdate) 
+0

Это кажется правильным, но по какой-то причине я не мог заставить его работать. Благодарим вас за сообщение вашего ответа. – Georgia2004

Смежные вопросы