Подсчет клетки на объекты

У меня снова возникла проблема:D Сначала немного информации: я пытаюсь скопировать данные из одной таблицы в другую (структура та же). теперь нужно увеличить одну ячейку, начиная с 1 в каждой группе (как в истории).

у меня есть эта таблица:

create table My_Test/My_Test2 (
my_Id Number(8,0),
my_Num Number(6,0),
my_Data Varchar2(100));

(my_Id, my_Num - это вложенный PK)

если я хочу вставить новую строку, мне нужно проверить, если значение в my_id уже существует.
если это правда, то мне нужно использовать следующий my_Num для этого идентификатора

у меня есть это в моей таблице:

My_Id   My_Num    My_Data
1       1         'test1'
1       2         'test2'
2       1         'test3'

если я добавлю сейчас строку для my_Id 1, строка будет выглядеть так: у меня есть это в моей таблице:

My_Id   My_Num    My_Data
1       3         'test4'

это звучит довольно просто, теперь мне нужно сделать это в SQL и на SQL Server у меня была такая же проблема, и я использовал это:

Insert Into My_Test (My_Id,My_Num,My_Data)
SELECT my_Id,
  (
    SELECT
      CASE (
          CASE MAX(a.my_Num)
            WHEN NULL
            THEN 0
            Else Max(A.My_Num)
          END) + b.My_Num
        WHEN NULL
        THEN 1
        ELSE (
          CASE MAX(a.My_Num)
            WHEN NULL
            THEN 0
            Else Max(A.My_Num)
          END) + b.My_Num
      END
    From My_Test A
    where my_id = 1
  )
  ,My_Data
From My_Test2 B
where my_id = 1;

этот выбор возвращает ноль, если в подвыборке строк не найдено

Есть ли способ, чтобы я мог использовать Макс в этом случае? и если он возвращает ноль, он должен использовать 0 или 1?

Редактировать: Я использую сейчас это:

Insert INTO My_Test  ( My_Id,My_Num,My_Data )
SELECT B.My_Id,
  (
    SELECT COALESCE(MAX(a.My_Num),0) + b.my_Num
    FROM My_Test A
    Where a.My_Id = b.My_Id)
  ,b.My_Data
FROM My_Test2 B
WHERE My_Id = 1

THX для Бхарата и OMG Пони

поздравил
Ауро

3 ответа

Решение

Попробуй это

Insert Into My_Test (My_Id,My_Num,My_Data)
SELECT my_Id,(
    SELECT MAX(NVL(My_Num,0)) + 1     
    From My_Test 
    where my_id = b.my_id
  )
,My_Data
From My_Test2 B
where my_id = <your id>;
Insert Into My_Test (My_Id,My_Num,My_Data) 
select My_id,coalesce(max(My_num),0),'test4' from My_Test
where My_id=1
group by My_id

Все решения имеют проблему в том, что они не работают в многопользовательской среде. Если два сеанса выдают этот оператор вставки одновременно, они оба получат одинаковую (my_id,my_num) комбинацию, и один из них завершится неудачно с уникальным нарушением ограничения ORA-00001. Поэтому, если вам нужно это для работы в многопользовательской среде, лучший совет - использовать только один столбец первичного ключа и заполнить его последовательностью. Также сохраните ваш столбец my_id, так как он является столбцом сортировки по группам или столбцом внешнего ключа. Если вашим конечным пользователям действительно нравится видеть столбец "my_num" в их (веб-приложении), вы можете использовать аналитическую функцию row_number.

Вы можете прочитать больше об этом сценарии в моем блоге: http://rwijk.blogspot.com/2008/01/sequence-within-parent.html

С уважением, Роб.

Другие вопросы по тегам