Witam,
Otóż mam tabelę kursy która zawiera pola id, id_kierowcy, trasa, data, godzina, uwagi ; (pole id_kierowcy jest UNIQUE - czyli nie możne się powtarzać ). W tabeli przykładowo są:
| ID | ID_KIEROWCY |TRASA | DATA | GODZINA | UWAGI |
---------------------------------------------------------------------
| 1 | 23 |EŁK | 23.04| 14:00 | |
---------------------------------------------------------------------
| 2 | 12 |POZNAN |12.05 | 12:30 | |
---------------------------------------------------------------------
Jak prostym zapytaniem wykonać wymianę kierowców, aby kierowca id 23 miał trasę 2 , a drugi trasę 1 , zaznaczam ze pole id_kierowcy jest UNIQUE
Pozdrawiam
Myślę to unique dla id_kierowcy to błąd.
Co wtedy gdy jeden kierowca będzie miał dwie trasy? Bo widzę że umieszczasz daty, więc przy różnych trasach nawet w czasie będą się kierowcy wymieniać.
23.04 będzie kierowca 23, ale za miesiąc 23.05, może to być już kierowca 124, a nie 23, a 23 będzie miał trasą do Sosnowca albo Radomia
UPDATE kursy SET id_kierowcy=35-id_kierowcy WHERE id_kierowcy IN (23,12) -- to 35 to suma tych id
@m to raczej nie zadziała bo sprawdzanie kluczy jest po update każdego wiersza więc już 1-szy update się nie powiedzie.
Tu jest rozwiązanie używając transakcji: https://stackoverflow.com/a/11207946
Porada @mmmmmmm niestety nie zadziała, ze względu na UNIQUE. Możesz:
1. Transakcje (@Pyton_000) - według mnie, najlepsze rozwiązanie.
2. Zamienić jedno id_kierowcy na jakieś inne, tymczasowe, które jeszcze nie występuje w bazie, zmienić to drugie id, na to, którego oczekujesz (wtedy jest już wolne) i finalnie na podstawie tymczasowego id zamienić w drugim miejscu (i znowu będzie już wolne, przykładowo 12, bo zmieniłeś już 12 na 23). Można też utworzyć jakąś tymczasową tabelę właśnie na taką operację i przechowywać w niej tymczasowe id.
3. Usunąć UNIQUE (DROP INDEX...), w zależności od potrzeby dodać:
SET SQL_SAFE_UPDATES = 0;
ADD UNIQUE INDEX `id_kierowcy_UNIQUE` (`id_kierowcy` ASC);
SET SQL_SAFE_UPDATES = 1;
Wywalanie kluczy i dodawanie ich na nowo to nie jest za dobry pomysł Wyobraź sobie tabel która ma powiedzmy 100GB danych Mówimy o przypadku zmiany takiej trywialnej. Bo jeślibyśmy zmieniali dużo wartości to wtedy warto to rozważyć bo update pójdzie dość szybko a indeks się odbuduje tylko 1x
Dziękuje za zainteresowanie,
Dlaczego UNIQUE id_kierowcy , nie che dopuścić aby na trasie było dwóch kierowców, a trasy są w czasie teraźniejszym,
Pierwszy raz słyszę o TRANSACTION
START TRANSACTION ; UPDATE kursy SET id_kierowcy= CASE WHEN id_kierowcy= 2 THEN -3 WHEN id_kierowcy= 3 THEN -2 END WHERE id_kierowcy IN (2,3) ; UPDATE kursy SET id_kierowcy= - id_kierowcy WHERE id_kierowcy IN (-2,-3) ; COMMIT ;
ustawia Ci po prostu ID na np. -12 a potem po zamianie obu na liczby ujemne robi odwrócenie.
Tylko jedna uwaga. `id_kierowcy` nie może być unsigned bo to nie zadziała (czyliu musi zezwalać na wpisanie do kolumny liczby ujemnej)
@fbi
Ale na trasie nie mogą być w tym samym czasie, a nie w różnych trasach.
I co wtedy gdy masz kierowców na długie trasy gdzie muszą się wymieniać. Wtedy na taką trasę zatrudnia się więcej niż 1 kierowcę.
Lepiej będzie wysłać zapytanie sprawdzające czy dany kierowca podczas dodawania do trasy nie jest już przypisany do jakiejś trasy.
@Pyton_000, oczywiście że to rozwiązanie najgorsze. Uszeregowałem rozwiązania jakie przychodzą mi do głowy od najlepszego (Twojego). Zainteresowany sam wybierze, co mu odpowiada. Osobiście rekordowo indeksowałem 76 godzin :-)
Spoko ja nie napisałem że jest złe :)Tylko tak jak powiedziałeś ostateczne rozwiązanie z tego co zaproponowałeś
fakt. mea culpa
Witam, ponownie - nadal walczę z tym zapytaniem , wiem ze temat bardziej już z PHP,
Poniższe zapytanie działa niepoprawnie , zamienia zmienne tylko na minusowe id (- ) , nie wiem czy dodatkowo trzeba dodać zmienne z minusami ?
$zamien = " START TRANSACTION"; $statement = $dbh->prepare($zamien); $statement->execute(); $zamien = "UPDATE planowanie_export SET id_kierowcy= CASE WHEN id_kierowcy= :nowy_kierowca THEN -:stary_kierowca WHEN id_kierowcy= :stary_kierowca THEN -:nowy_kierowca END WHERE id_kierowcy IN (:nowy_kierowca,:stary_kierowca)"; $statement = $dbh->prepare($zamien); $statement->execute( http://www.php.net/array( ':nowy_kierowca' => $_POST["nowy_kierowca"], ':stary_kierowca' => $_POST["stary_kierowca"] ) ); $zamien = "UPDATE planowanie_export SET id_kierowcy= - id_kierowcy WHERE id_kierowcy IN (-nowy_kierowca,-:stary_kierowca)"; $statement = $dbh->prepare($zamien); $statement->execute( http://www.php.net/array( ':nowy_kierowca' => $_POST["nowy_kierowca"], ':stary_kierowca' => $_POST["stary_kierowca"] ) ); $zamien = "COMMIT"; $statement = $dbh->prepare($zamien); $statement->execute();
Zapytania możesz uprościć do:
UPDATE kursy SET id_kierowcy = -id_kierowcy WHERE id_kierowcy IN (2,3); UPDATE kursy SET id_kierowcy = 5 + id_kierowcy WHERE id_kierowcy IN (-2,-3);
Zamiast "-:stary_kierowca" daj po prostu ":stary_kierowca" a jako wartość przekazuj wartość ujemną.
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)