简体   繁体   中英

Alternative to bubble sort in MySQL


the problem lies most likely in fact, I am not asking google(or stackoverflow) the right question, but since this simple thing is driving me nuts. Sorry for long post, but want to make situation clear.

I have a mysql table of records ID, person_name, priority

ID and person_name are quite selfexplanatory, the priority is used to sort the records descending order - highest = top priority.

I have following records, for simplicity, IDs correspond the sorting order:

1, "John A", 3
2, "John B", 2
3, "John C", 1
4, "John D", 0

This worked fine until I imported a record from a export from other machine, suddenly there are two records with same priority.

1, "John A", 3
2, "John B", 2
3, "John C", 1
5, "John E", 1
4, "John D", 0

When the records are now ordered by priority DESC, name ASC, the ID3 and ID5 are sorted alphabetically which does not correspond the situation. If user wants to shift priority of ID5 to be HIGHER than ID2, I can't just increment the priority, since it would match ID2 and ID5 would appear BELOW ID2 due to alpha-order.

Question: Is there a way to do this more EFFECTIVELY than this, or just completely different approach:

  1. NEAREST_PRIORITY = Determine priority of nearest record with higher priority
  2. Increase priority of all records with priority > NEAREST_PRIORITY by 1
  3. Set current record priority = NEAREST_PRIORITY+1

This will actually not work quite well if there are several records with NEAREST_PRIORITY...

thanks for reading long post and any ideas.

Interesting problem, it depends how you resolve the priority clashes of imported records. Let's assume that, if there's a clash, then imported records get priority. Before import multiply all priorities by 2, then import the new records but multiply their priorities by 2 and add 1 during the import. Now you'll have:

1, "John A", 6
2, "John B", 4
5, "John E", 3
3, "John C", 2
4, "John D", 0

If you need your priorities to be continuous, or you do a lot of imports, then you'll have to do some work to reset the numbers but at least the order is correct.

You can use the same solution for a priority change where there's a clash, multiply by two then set the new priority to be new priority + 1. So to move ID4 to before ID5 it's new priority would be (3 * 2) + 1 and you'd have:

1, "John A", 12
2, "John B", 8
4, "John D", 7
5, "John E", 6
3, "John C", 4

Again, things will escalate rapidly if you do this so you might want to reset the numbers. This answer shows an example of sequential numbering that you could adapt.

I was thinking about linked lists and implementing a priority table, something like

{ id, userId, comesAfterUserId, comesBeforeUserId }

Then any priority move should only change two entries. But I can't work out how to sort that in SQL directly, so you'd have to process in your app. I have a feeling that's a more elegant solution but the multiple by two should work too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM