views:

57

answers:

3

hey

i got a problem once again :D a little info first: im trying to copy data from one table to an other table(structure is the same). now one cell needs to be incremented, beginns per group at 1 (just like a histroy).

i have this table:

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

(my_Id, my_Num is a nested PK)

if i want to insert a new row, i need to check if the value in my_id already exists.
if this is true then i need to use the next my_Num for this Id.

i have this in my Table:

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

if i add now a row for my_Id 1, the row would look like this: i have this in my Table:

My_Id   My_Num    My_Data
1       3         'test4'

this sounds pretty easy ,now i need to make it in a SQL and on SQL Server i had the same problem and i used this:

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;

this Select gives null back if no Rows are found in the subselect

is there a way so i could use max in the case? and if it give null back it should use 0 or 1?

Edit: Im usung now this:

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 to Bharat and OMG Ponies

greets
Auro

A: 

Try this one

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>;
Bharat
It does work but if the ID dont exists in the Table all inserted rows will have a `null`
Auro
I think that you must make ID as primary key.
Bharat
Id is a clustered PK with my_Num
Auro
A: 
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
Madhivanan
While copying a source table to destination table, if we use this statement it will insert only one record in destination table even though there are multiple records in source table.
Bharat
Then, you need to remove the where clause
Madhivanan
A: 

All solutions have a problem in that they don't work in a multi user environment. If two sessions issue that insert statement at the same time, they would both get the same (my_id,my_num) combination, and one of them will fail with a ORA-00001 unique constraint violation. Therefore, if you need this to work in a multi user environment, the best advice is to use only one primary key column and populate it with a sequence. Keep your my_id column as well, as that is a sort-of-grouping column or foreign key column. If your end users really like to see the "my_num" column in their (web) application, you can use the row_number analytic function.

You can read more about this scenario in this blogpost of mine: http://rwijk.blogspot.com/2008/01/sequence-within-parent.html

Regards, Rob.

Rob van Wijk
Well that’s a good point! But this SQL statement will be only used from one person, and even if there were more sessions they wouldn’t work on the same ID (ID is something like an ID of a person and my_Num is a history. What I’m doing is merge 2 person's together that’s the reason to count it up this Number) -And btw im not permitted to use sequence and I think it wouldn’t work for this or you want to do a sequence for each ID?Regards, Auro
Auro