3

Example:

INDEX | SOME_DATA

1 | some_data1

3 | some_data3

4 | some_data4

5 | some_data5

I want to do an INSERT to add ---> 2 | some_data2. Is there an SQL command or some way of doing this?

[edit]
OK. Maybe if i explain every thing what i want to accomplish you'll see why i'm trying to do what i want to do. I creating a Web admin page in php that simply displays data from a database table.now these displayed rows are "draggable". example,you can drag row #2 to say, row #4. now on the "mouseup" event, i want to save the new order in the database.

1| data1 -------------------------> 1| data1
2| data2 -------After Drag-----> 3| data3
3| data3 -------------------------> 4| data4
4| data4 -------------------------> 2| data2
See my problem? i cant merely just update the value in the INDEX column for the one value that was dragged. I'll have to update all the values that were dragged over. 3 has to become a 2, 4 a 3 and 2 has to become the new 4. Thats too many sql updates (expecially if the table is larger). So i want to remove row #2 and insert it in its correct location.

Just a coder
  • 15,480
  • 16
  • 85
  • 138
  • If `INDEX` is your auto-increment column, I believe you can just specify the row number in your `INSERT` statement. It won't appear (in phpMyAdmin for example) in the proper order unless you're sorting that column, though. – drudge Nov 08 '10 at 19:21
  • you can't depend on the natural order of rows, for anything really. and I doubt you can change it easily, other than deleting and re-inserting every row after your insertion. – Rob Nov 08 '10 at 20:12

4 Answers4

6

Just insert the data; tables are not fundamentally ordered. The only ordering of table results occurs when you define it yourself in your select statement.

Edit: if what you want is to have a separate ordering, you would be well served by having a separate "order" column. I'd recommend making it of type float, so you can insert entries anywhere between other entries without requiring any updating. For example, if you have entry "A" with "order" column value "1", entry "B" with "order" column value "2", and you want to insert entry "C" so it shows up between entry "A" and entry "B", just insert it with the "order" column value set to 1.5 (1 + 2 / 2.0). That way, you can perform your select with an "order by" on your "order" column, and things should turn out the way you want. Floats are a reasonably good solution to this issue, since there's enough space to support a lot of "in-between" adds.

Paul Sonier
  • 38,903
  • 3
  • 77
  • 117
  • does MySQL let you insert a new record and specify the index? – hunter Nov 08 '10 at 19:21
  • @hunter: yes; in this case, "index" is your column name in the table. – Paul Sonier Nov 08 '10 at 19:23
  • 2
    +1 for mentioning that SQL tables are set-based and are not "ordered" in and of themselves. Important concept! – Dan J Nov 08 '10 at 19:34
  • @McWafflestix: but, what i really want to know is, can you specify which row the data is inserted into? like can i tell it to insert @ index location #2 as shown in the example above? – Just a coder Nov 08 '10 at 19:34
  • 1
    @djacobson, actually there is a natural order to rows in MySQL -- the insert order -- and you can reorder it with an ALTER TABLE command. But it's also true that you should *think* of the data as collection-based and unsorted, and not use the natural order for any purpose. @the face, yes you can do that. See the update on my answer. But also see the notes I added explaining why this should not be important to you. – Ben Lee Nov 08 '10 at 19:37
  • 1
    @theface: with SQL, you're inserting data into a row; the order in which rows appear is ONLY determined by your SQL statement. So a "SELECT * from your_table" can technically give the rows in any order; to get them in order of ascending index value, you'd have to use something like "SELECT * from your_table ORDER BY index ASC". – Paul Sonier Nov 08 '10 at 19:39
  • @McWafflestix: i updated my question. i thought i was to vague origionally – Just a coder Nov 08 '10 at 20:12
  • @Ben Lee Interesting! I didn't know that about MySQL. Does the "natural order" serve a specific purpose? – Dan J Nov 08 '10 at 21:02
  • @McWafflestix: ok man, i had that idea, but i wasnt sure if there was a better way. Thanks for the confirmation. – Just a coder Nov 08 '10 at 21:05
  • @djacobson. No, not really. That's just the order that rows are returned in a result set if you don't specify an ORDER BY clause. And it only applies to MyISAM, which keeps the rows sorted by insert order. InnoDB always keeps the rows ordered by primary key (if there is one). Again, it's mostly just database internals and should never be relied upon. – Ben Lee Nov 08 '10 at 21:06
5

You should just be able to add it like regular:

INSERT INTO some_table (index, some_data) VALUES (2, 'some_data2')

After inserting, if you actually want the rows to be ordered by index, run this:

ALTER TABLE some_table ORDER BY index;

In general the order is really unimportant though. You should be using indexes for columns you do finds on, and ORDER BY when getting result sets. You should not rely on the insert order of rows in the table for either optimizing or sorting.

Ben Lee
  • 52,489
  • 13
  • 125
  • 145
  • but wouldnt this add the data to the bottom of the table? – Just a coder Nov 08 '10 at 19:26
  • 1
    @the face, if the order you receive rows is important to you, you should specify it by using `order by` on some criteria in your query. In this case you can use `order by index`. – Ian Mackinnon Nov 08 '10 at 19:31
  • 1
    @the face -- I added an update to explain how to reorder the rows. In general the order is really unimportant though. You should be using indexes for columns you do finds on, and ORDER BY when getting result sets. You should not rely on the insert order of rows in the table for either optimizing or sorting. – Ben Lee Nov 08 '10 at 19:32
  • +1 for `alter table ... order by`. Worth reading the recommendations and caveats for this in [the documentation](http://dev.mysql.com/doc/refman/5.1/en/alter-table.html). – Ian Mackinnon Nov 08 '10 at 19:37
2

Yes, you can specify the primary key of the row when you insert.

insert into yourtablename (index, some_data) values (2, "some_data2");

It's a bad idea however to worry about having contiguous primary keys. Their job should be to uniquely identify the row and nothing more.

Ian Mackinnon
  • 13,381
  • 13
  • 51
  • 67
  • @hunter, if you're inserting a row which has never been used then I agree with you. Though a missing row suggests there was a previous value there, in which case I think in many cases it's better to append (to the db and enum) so that existing software receives an error and not the wrong value if it requests that row. – Ian Mackinnon Nov 08 '10 at 19:29
1

Okay, I'm answering again because your update shows you are asking a completely different question than everyone thought you were.

The method that you described -- update the index of the moved row and every one in the list after it -- is exactly the right method here.

Why do you say that "that's too many sql updates"? As long as you have a MySQL index applied to the index column, those updates will be lightening fast, even for very large lists (they will be on the order of milliseconds).

I think you are either pre-optimizing, or you don't have an index defined. To add an index (if you don't already have one), run this command:

CREATE INDEX row_index_index ON `some_table` (`index`);

You also might want to reconsider renaming your "index" column to something like "position" to avoid confusion about nomenclature with an actual MySQL index.

Ben Lee
  • 52,489
  • 13
  • 125
  • 145
  • The thing is, i'm not too good at SQL, so i dont really know how fast its gonna be. So you say it will be fast (even if that table has about 200 records) ? If that's true then i will, stick with my original. awaiting your response. – Just a coder Nov 09 '10 at 13:56
  • Yes, after adding the index, it will be very fast. Even if the table has 200 *thousand* records, and even if the list being changed has dozens of items. – Ben Lee Nov 09 '10 at 16:02