Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: autonumerowanie i update
Forum PHP.pl > Forum > Bazy danych > MySQL
kitol
Mam tabelę a w niej pola:kolejność i nazwa. kolejnośc jest AUTOINCREMENT. W tabeli znajduje się już pewna ilość rekordów. Kilka z nich zostało usuniętych i powstały "dziury w numeracji". Jak te dziury usunąć? Chcę aby w polu kolejność rekordy były ponumerowane kolejnymi liczbami. Myślałem o stworzeniu dodatkowej tabeli z polem AUTOINCREMENT i skopiowaniu wszystkich rekordów w kolejności rosnącego pola "kolejnosc". Z pewnaością by działało, ale podejrzewam, że da się to zrobić operując na tej jednej tabeli za pomocą jednego UPDETE`a. Ktoś ma pomysł jak?
ActivePlayer
  1. UPDATE tabela t SET kolejosc = (SELECT max(kolejnosc)+1 FROM tabela tt WHERE tt.kolejnosc < t.kolejnosc)

domyslam sie ze cos takiego moglo by zadzialac
kitol
Niestety nie działa:

#1093 - You can't specify target table 'tescik' for update in FROM clause
frickle
A ja bym zrobił tak:

  1. <?php
  2. $q = 'select * from TABELA';
  3. $w = mysql_query($q);
  4. $ile = mysql_num_rows($w);
  5. for($i=1;$i<=$ile;$i++)
  6.  {
  7.  $r = mysql_fetch_assoc($w);
  8.  $q2 = 'insert into TABELANOWA values ($r['pierwszakolumna'],$r['drugakolumna'], ... ,$r['ostatniakolumna'])';
  9.  }
  10. ?>


tylko w drugim zapytaniu nie podajesz wartości tej kolumny która ma autoincrement, tylko po prostu wstawiasz kolejno i będziesz miał ponumerowane od 1 w góre po kolei...
kitol
Coś podobnego mam teraz, jednak nie jest to zbyt wydajne i może obciążać serwer w przypadku częstego wywoływania dla dużej ilości rekordów. Poszukuję rozwiązania z jednym zapytaniem. Mam nadzieję że da się to zrobić.

Wymyśliłem rozwiązanie z zastosowaniem tabeli pomocniczej:

  1. CREATE TABLE temp (
  2. num_auto INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  3. num INT NOT NULL
  4. );
  5.  
  6. INSERT INTO temp (num) SELECT TABLE.kolejnosc FROM TABLE ORDER BY TABLE.kolejnosc;
  7.  
  8. UPDATE TABLE, temp SET TABLE.kolejnosc=temp.num_auto WHERE TABLE.kolejnosc=temp.num;


Da się jeszcze prościej (bez php)?
ww-06
Cytat(kitol @ 31.01.2007, 10:56:55 ) *
Da się jeszcze prościej (bez php)?


Ja bym poszedł na całość:
  1. ALTER TABLE `tabela` DROP `nrauto` ;
  2. ALTER TABLE `tabela` ADD `nrauto` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ;

czyli wywalam całe pole nrauto i tworzę je na nowo, wtedy numerki same zaczynają się od 1.
Nie wiem tylko czy coś takiego jest w Twoim wypadku dopuszczalne? Ale chyba zadziała najszybciej i bez php.
Jeśli Ci zależy na wstawieniu tego pola na samym początku tablicy to pamiętaj jeszcze o "FIRST" na końcu drugiej komendy.
Jednak przy tym wszystkim mała uwaga: pola typu "auto_increment" raczej nie należy się w ogóle "tykać", więc takie przenumerowania to rób sobie w innych polach dodatkowych nie-"auto_increment".
kitol
Niestety nie mogę tego zrobić. W danej tabeli pole kolejnosc nie jest unikalnym kluczem. Jego wartości mogą się powtarzać ponieważ tabela informacje o wielu obiektach pogrupowanych wg innej kolumny. Konkretnie chodzi o zbiór galerii obrazków - grupowanie wg kolumny galeria, kolejność w galerii wg kolumny o tej samej nazwie. Zatem przenumerowanie przez wywalenie kolumny i jej odtworzenie odpada.

Poszukuję rozwiązania w stylu UPDATE tabela SET cośtam WHERE galeria=nr_galerii. już raczej tylko dla sportu
ponieważ poradziłem sobie w inny sposób. Podczas usuwania rekordów z tabeli dodałem zaraz po delete:

  1. UPDATE TABLE SET kolejnosc=kolejnosc-1 WHERE kolejnosc> kolejnosc_usuwanego_rekordu


Lepiej zapobiegać powstawaniu dziur niż je potem naprawiać snitch.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.