Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ MySQL _ Zamian danych w tabeli między dwoma rekordami

Napisany przez: fbi 19.04.2018, 00:28:51

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

Napisany przez: Tomplus 19.04.2018, 02:56:48

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 smile.gif

Napisany przez: mmmmmmm 19.04.2018, 07:23:29

  1. UPDATE kursy SET id_kierowcy=35-id_kierowcy WHERE id_kierowcy IN (23,12) -- to 35 to suma tych id

Napisany przez: Pyton_000 19.04.2018, 07:57:16

@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

Napisany przez: Lukeup 19.04.2018, 08:40:11

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ć:

  1. SET SQL_SAFE_UPDATES = 0;

(wtedy nie jest wymagana kolumna-klucz), wykonać zapytanie (@mmmmmmm) i potem przywrócić UNIQUE, eg.
  1. ADD UNIQUE INDEX `id_kierowcy_UNIQUE` (`id_kierowcy` ASC);

i w zależności od potrzeb, przywrócić bezpieczne aktualizacje:
  1. SET SQL_SAFE_UPDATES = 1;

Napisany przez: Pyton_000 19.04.2018, 08:41:59

Wywalanie kluczy i dodawanie ich na nowo to nie jest za dobry pomysł wink.gif Wyobraź sobie tabel która ma powiedzmy 100GB danych wink.gif 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

Napisany przez: fbi 19.04.2018, 09:39:47

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 sad.gif

  1. START TRANSACTION ;
  2. UPDATE kursy
  3. SET id_kierowcy=
  4. CASE
  5. WHEN id_kierowcy= 2 THEN -3
  6. WHEN id_kierowcy= 3 THEN -2
  7. END
  8. WHERE id_kierowcy IN (2,3) ;
  9.  
  10. UPDATE kursy
  11. SET id_kierowcy= - id_kierowcy
  12. WHERE id_kierowcy IN (-2,-3) ;
  13. COMMIT ;


Moża poprosić o wyśnienie co oznaczają liczby ujemne ,

Napisany przez: Pyton_000 19.04.2018, 09:45:11

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)

Napisany przez: Tomplus 19.04.2018, 11:30:37

@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.

Napisany przez: Lukeup 19.04.2018, 16:23:29

@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 :-)

Napisany przez: Pyton_000 19.04.2018, 18:28:08

Spoko ja nie napisałem że jest złe :)Tylko tak jak powiedziałeś ostateczne rozwiązanie z tego co zaproponowałeś smile.gif

Napisany przez: mmmmmmm 20.04.2018, 07:12:11

fakt. mea culpa

Napisany przez: fbi 20.04.2018, 20:27:29

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 ?

  1. $zamien = " START TRANSACTION";
  2. $statement = $dbh->prepare($zamien);
  3. $statement->execute();
  4. $zamien = "UPDATE planowanie_export
  5. SET id_kierowcy=
  6. CASE
  7. WHEN id_kierowcy= :nowy_kierowca THEN -:stary_kierowca
  8. WHEN id_kierowcy= :stary_kierowca THEN -:nowy_kierowca
  9. END
  10. WHERE id_kierowcy IN (:nowy_kierowca,:stary_kierowca)";
  11. $statement = $dbh->prepare($zamien);
  12. $statement->execute(
  13. http://www.php.net/array(
  14. ':nowy_kierowca' => $_POST["nowy_kierowca"],
  15. ':stary_kierowca' => $_POST["stary_kierowca"]
  16. )
  17. );
  18. $zamien = "UPDATE planowanie_export
  19. SET id_kierowcy= - id_kierowcy
  20. WHERE id_kierowcy IN (-nowy_kierowca,-:stary_kierowca)";
  21. $statement = $dbh->prepare($zamien);
  22. $statement->execute(
  23. http://www.php.net/array(
  24. ':nowy_kierowca' => $_POST["nowy_kierowca"],
  25. ':stary_kierowca' => $_POST["stary_kierowca"]
  26. )
  27. );
  28. $zamien = "COMMIT";
  29. $statement = $dbh->prepare($zamien);
  30. $statement->execute();



Przepraszam w Lini 20 pominąłem ":" - Po uzupełnieniu działa smile.gif

Napisany przez: trueblue 20.04.2018, 21:09:25

Zapytania możesz uprościć do:

  1. UPDATE kursy
  2. SET id_kierowcy = -id_kierowcy
  3. WHERE id_kierowcy IN (2,3);
  4.  
  5. UPDATE kursy
  6. SET id_kierowcy = 5 + id_kierowcy
  7. WHERE id_kierowcy IN (-2,-3);

Napisany przez: Pyton_000 21.04.2018, 11:52:06

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)