views:

37

answers:

2

Here's a problem for the PHP-juggler in you. I want to use plain-ol' mysql_* functions of PHP.

I have the following MySQL table:

+-----+-----------------+
|  id | thread          |
+-----+-----------------+
|  14 | 01/             |
|  14 | 02/             |
|  14 | 03/             |
|  15 | 01/             |
|  22 | 01/             |
|  24 | XXX             |
|  24 | XXX             |
|  24 | XXX             |
|  24 | XXX             |
|  32 | XXX             |
|  32 | XXX             |
+-----+-----------------+

The "XXX" values are my making. I want to change (UPDATE) that table to this one:

+-----+-----------------+
|  id | thread          |
+-----+-----------------+
|  14 | 01/     <-      |
|  14 | 02/             |
|  14 | 03/             |
|  15 | 01/     <-      |
|  22 | 01/     <-      |
|  24 | 01/     <-      |
|  24 | 02/             |
|  24 | 03/             |
|  24 | 04/             |
|  32 | 01/     <-      |
|  32 | 02/             |
+-----+-----------------+

On every new value of the "id" field (where the "<-" is; my making, also), the "thread" field value has to reset itself to "01/" and continue incrementing until a new value of "id" is found.

I've tried querying with COUNT(id) to increment somehow. I tried storing in arrays. I thought of mysql_data_seek() also. Alas, I don't seem to pull it off.


I got the "thread" format right, though:

$thread = $i < 10 ? "0$i" : $i;

So, if it's bigger than 10, it doesn't get a leading zero. But this is just the fun part.


Any help would be appreciated.

Thanks

A: 

Set PRIMARY KEY the tuple (id,thread) and set thread (but not the id!) as AUTO_INCREMENT, then run the query

INSERT INTO mytable (id) VALUES (24),(24),(32),(24),(32),(24)

and thread attribute should be set autoincrementally. If you insist on "0n/" form, I suggest to create thread_string attribute and create BEFORE UPDATE trigger according to NEW.thread attribute. Does it work?

Jan Turoň
A like the AI trick. Still, I need a way to batch-modify that table. In actuality, I have some 2300 rows.
nush
2300 records is no problem. I would create another empty table (new_table) with primary key set as I suggested above and then run "INSERT INTO new_table (id) SELECT id FROM old_table" - and you are done. Good luck :-)
Jan Turoň
+1  A: 
SET @oldid = 0;
SET @counter = 0;
UPDATE tablename
SET thread = CONCAT(
  LPAD(
     CAST(IF(id = @oldid,
       @counter := @counter + 1,      -- same id, increment
       @counter := (@oldid := id)/id) -- other id, set to 1 
       AS UNSIGNED),
     2,'0'),                          -- pad with '0'
  '/')                                -- append '/'
WHERE thread = 'XXX'                  -- or enumerate the whole thing if need be
ORDER BY id, thread;

Which can just be fed to "plain ol' mysql_query" (3 in a row: feed the SET & UPDATE queries separately, alternatively forget about SETting anything, I just hate uninitialized variables ;)

Wrikken
nush
That you cannot send them as one query, but as 3 (`mysql_query('SET...');mysql_query('SET...');mysql_query('UPDATE...');`. It uses user-defined variables, and the main complexity comes from battling against SQL: you cannot `set` a variable unless it's part of some expression, hence a simple `@counter := 1, @oldid := id` has become a convoluted expression with the same outcome: `@counter := (@oldid := id)/id`, which can result in a float, so we cast back to integer.
Wrikken
Nice. Could you please explain or send a link how long will endure the mysql variable @counter: until the end of query, end of php script or reset mysql server? I can not find it.
Jan Turoň
Until the end of the connection, hence the `SET` at the start (to prevent a previous counter possibly fouling things up), see http://dev.mysql.com/doc/refman/5.0/en/user-variables.html (Be aware: if you use persistent connecections they can stil be set from a previous request).
Wrikken