views:

125

answers:

4

I have a table that stores "records" and already has primary key.

Table A
=======
id (INT) PK auto_increments
project_id (INT)
record_text (TEXT)

This table stores "records" for all of my projects. It is desirable to have a secondary key that auto increments for the projects.

Example: If project 1 had id's of (1,5,8,9). It would be desirable to store them and present them to the user as (1,2,3,4).

I do not have the ability to use TRANSACTIONS and I'm having trouble thinking of a way of doing this without causing concurrency issues.

Hopefully I got my problem across clearly. Thank you in advance for the help.

Edit (Example): Assuming the structure:
id, project_id, record text
1 1 testing
2 1 testing
3 2 testing
4 1 testing

My ID's for project 1 would 1,2,4. But I'm looking for a way to store and display them for project 1 as 1,2,3

A: 

You can create your project_id field to auto_increment as well without making it a key.

jaywon
I think the problem he's having stems from the deletion of rows rather than the auto increment itself. The primary ID is probably auto_incremented, but it won't solve his problem. He's saying that if you have rows 1, 2, 3, and 4, and delete row 3, how can you display the rows 1, 2, 4 as 1, 2, 3 and keep the reference to that number.
Crowe T. Robot
+1  A: 

I can't tell from your question, but if you just want to present a cleanly numbered list to the user; I would handle this in the UI; and not even worry about storing it in the database.

If you really want to store it in the DB, I'd look into using a trigger that fires on INSERTED, and sets your value there.

Jim B
Noting Crowe's comment, you'll also need to build something to renumber in the case of deletes as well
Jim B
It is a good thought on just displaying it. I think in the long run I'd prefer having this value for good.My first thought was to just do the insert, and then increment the project level ID. It seems like I should be doing it a better way.
ws0x9
Can you elaborate on your reasoning for having this column?
Jim B
So the users having something to reference "records" by. Unfortunately the client doesn't want to skip the ID's.
ws0x9
Hmm, it still seems to me like that might not be needed. The client might be "referencing" that number, but when it actually comes to doing stuff, everything should be operating off your PK.
Jim B
It will be... I'm just not seeing how I'll be able to do it just through the UI. Although I didn't add them for the sake of the example, I have other columns that I'll let the user filter out results besides the project_id.
ws0x9
+1  A: 

You can generate row numbers using MySQL variables:

select
    id
,   project_id
,   if (@last_id = project_id, @n, @n := @n + 1) as RunningProjId
,   record_text
,   @last_id := project_id
from (select @n := 0, @last_id := -1) r, A
order by project_id

The row with the if increases the @n variable if the project differs from the last row. This relies on the order by clause to function. The row with `@last_id := project_id saves the project_id for reference when the next row is selected.

The first part of the from clause is the variable initialization. The second part is your table called A.

Andomar
I tried applying this query but `RunningProjId` renumbered the `project_id`. I'm looking at renumbering `id`. I'm messing with it now...Seems promising though.
ws0x9
Yeah all that I had to do was change @last_id = project_idto @last_id = id
ws0x9
Forgot to say it but thank you Andomar!
ws0x9
A: 

I'm not sure what I was thinking, too late in the day probably, but I was able to achieve this by adding a column to the table:

id, pid, project_id, record_text

pid being the numbering system for the project.

The INSERT:

INSERT INTO A (id, pid, project_id, record_text) 
VALUES (
    NULL, 
    (SELECT COALESCE(new_id, 0) + 1 FROM (SELECT MAX(new_id) AS new_id FROM atest WHERE project_id = 1) AS x),
    1,
    'some text'
);

Now as my project changes my pid, id based off the project, auto-increments too:

id    pid    project_id    record_text
1     1      1             testing 123
2     2      1             testing 123
3     1      2             testing 123
4     3      1             testing 123

Thank you all for your input and I apologize for my poor description of the problem.

ws0x9