views:

58

answers:

4

Suppose you have a table where you store the musical preferences of people, and you'd like to give users the ability to rank their preferences. At the time of insertion, the rank field should be calculated automatically. Later, however, the user should have the ability to edit his rankings.

id, memberid, trackid, rank

EDIT: It appears the best way to do this is to find the get the max for a member's existing ranks and add one...

+1  A: 

Make rank auto increment? It will just increment that field everytime you make an insert. Like id.

Rereading your question i think I am misunderstanding it. Do you want rank to be automatic or is it a field that users set depending on subject? if its the former I don't understand whats wrong.

Iznogood
I want both... at the time of insert for it to be automatic, but then later for users to be able to edit that...
Mel
+2  A: 

How are your users going to rank the tracks? Will they order them one after the other in some user interface?

If this is the case, I suggest delegating the rank numbering to the client-side (the interface). Therefore if you'd be having an interface that allows users to drag and move tracks around to rank them in order, simply assign them a sequential rank number, and when they hit save, send this information to the database.


UPDATE:

If you want a new record to always be ranked last you could simply get the MAX(rank) WHERE memberid = ? and then INSERT the new row with a rank + 1 as you suggested in the question. Wrapping everything in a transaction will guarantee atomicity.

Daniel Vassallo
Yes, they will have the ability to do that, but at the time of inserting a new record, I'll need the rank to be automatic, and take into account the ranking of existing records (for each user)
Mel
@Mel: How should the database calculate the rank at the time of insertion? Should a new record be the last in the rank automatically? If that is the case, you could simply get the `MAX(rank) WHERE memberid = ?` and insert with a rank+1 as you suggested in the question. Wrapping everything in a transaction will guarantee atomicity... (Updated the answer with the info in this comment)
Daniel Vassallo
+2  A: 

It sounds like you want to rank the newly inserted item automatically at the bottom.

INSERT INTO Prefs (MemberId, TrackId, Rank)
   SELECT   @MemberID, @TrackID,
            MAX(ISNULL(Rank,0))+1
   FROM Prefs
   WHERE MemberId = @MemberID

Aside: Why not keep rank null until the user actually gives each item a rank value? Present the user with all the items, and when they fill in (or not!), the rank, then run the UPDATE statement for each item.

p.campbell
Its like a roulettes table. Wich of use got the question right! Not me I am beginning to think. Got confused by his story of getting the value and adding +1.
Iznogood
hmm... I'm not sure if auto-increment will work in a many-to-many relationship... this is a joiner table... initially ranking them by primary key would work, and then i would have to copy those values to a rank field, giving the user a chance to re-arrange them...
Mel
re comment: I want the ranking to initially be automatic (at the time of insert) but later to be changeable by the user in some sort of interface...
Mel
A: 

I think the question you're asking is "how do I know what the next rank should be for each user?"...but I'm not sure.

If so, you could simply cheat and keep a "max rank" field in the users table for each userID. You'd query that value before inserting a new ranking and increment it for both the users table and the rankings table.

Alternatively, you could use a "select max(rank) from rankings where memberid = ?" type query to have the database compute it for you. Not the most efficient, but for an iTunes-like DB it would probably be managable (that is, as long as the number of songs * users isn't "too" large).

Drew Hall
Drew, you are partially correct... yes, as I said to Aaron, the user will have the ability re-rank in the interface, but at the time of inserting a new record, I'll need the rank to be automatic, and take into account the ranking of existing records (for each user)
Mel
@Mel Ok go edit your question, make it clearer please. Then someone will ajust his answer accordingly and we can move on.
Iznogood