powiedzmy ze mamy tabele categories (przytocze ta moja wersje

a w niej wiersze
Kod
categories_id | categories_order
----------------------------------
... | ...
1 | 13
2 | 14
... | ...
chodzi nam o zamienienie przy tych dwoch wierszach wartosci kolumny categories_order
mozna to zapisac tak:
UPDATE categories c, (SELECT 1 AS categories_id, 14 AS categories_order
UNION
SELECT 2 AS categories_id, 13 AS categories_order) AS nowe_dane
SET c.categories_order = nowe_dane.categories_order
WHERE c.categories_id = nowe_dane.categories_id
czyli:
SELECT 1 AS categories_id, 14 AS categories_order
UNION
SELECT 2 AS categories_id, 13 AS categories_order
tworzy nam to tabele z 2 wierszami
Kod
categories_id | categories_order
----------------------------------
1 | 14 *(1)
2 | 13 *(2)
i nastepnie to wpada w update i dla categories_id = 1 jest ustawiane categories_order na 14 a dla categories_id = 2 categories_order ustawiane na 13
czyli mamy update 2 wierszy za pomoca jednego zapytania ale potrzebowalibysmy jeszcze jednego zapytania na pobranie danych do tego zapytania
my chcemy zrobic zapytanie gdzie jedyna wiadoma jest id kategori ktora chcemy przesunac w gore o jeden czyli catgories_id='2'
na poczatku utworzymy zapytanie ktore zwroci wiersz *(2) z powyzszej tabeli czyli id = 2 i order = 13
SELECT categories_id, ord.categories_order
FROM categories, (SELECT categories_order
FROM categories WHERE categories_order < (SELECT categories_order
FROM categories WHERE categories_id = 2
LIMIT 1 )
ORDER BY categories_order DESC LIMIT 1 ) AS ord
WHERE categories_id = 2
zaczynajac od zapytania najbardziej zagniezdzonego
SELECT categories_order
FROM categories WHERE categories_id = 2
LIMIT 1
to zwroci nam categories_order dla naszej przesowanej kategori id = 2 czyli 14 i to wstawiam do zapytania mniej zagniezdzonego
SELECT categories_order
FROM categories WHERE categories_order < (14)
ORDER BY categories_order DESC LIMIT 1
to znowy zwroci nam najwiesza wartosc categories_order mniejsza od 14 czyli 13
czyli ogolnie cale zapytanie wyglada mniejwiecej tak
SELECT categories_id, ord.categories_order
FROM categories, 13 AS ord
WHERE categories_id = 2
no i to da wynik w postaci tabeli z jednym wierszem
Kod
categories_id | categories_order
----------------------------------
2 | 13
polowe mamy teraz jeszcze wiesz z id = 1 i order = 14
SELECT c1.categories_id, ord.categories_order
FROM categories c1, (SELECT categories_order
FROM categories WHERE categories_id = 2) AS ord
WHERE c1.categories_order < (SELECT categories_order
FROM categories WHERE categories_id = 2
LIMIT 1 )
ORDER BY c1.categories_order DESC LIMIT 1
a wiec zaczynajac od zapytania zagniezdzonego
SELECT categories_order
FROM categories WHERE categories_id = 2
to zwraca nam categories_order = 14 wiec zapytanie wyglada teraz tak
SELECT c1.categories_id, ord.categories_order
FROM categories c1, 14 AS ord.categories_order
WHERE c1.categories_order < (SELECT categories_order
FROM categories WHERE categories_id = 2
LIMIT 1 )
ORDER BY c1.categories_order DESC LIMIT 1
SELECT categories_order
FROM categories WHERE categories_id = 2
LIMIT 1
to zwroci nam categories_order dla naszej przesowanej kategori id = 2 czyli 14 (w sumie to nie potrzebenie bo bylo to zrobione w poprzednim zapytaniu i mozna to znalesc pod aliasem ord.categories_order wiec na koncu napisze krotsza wersje tego calego zapytania)
SELECT c1.categories_id, ord.categories_order
FROM categories c1, 14 AS ord.categories_order
WHERE c1.categories_order < 14
ORDER BY c1.categories_order DESC LIMIT 1
to cale zapytanie zwroci nam id wiersza ktory ma byc zamieniony z naszym wybranym wierszem czyli 1 i categories_order 14
Kod
categories_id | categories_order
----------------------------------
1 | 14
teraz te 2 selecty laczymy za pomoca union i wstawiamy do update i to wszystko

mam nadzieje ze te wypociny chociaz troche sa zrozumiale
tak wiec wersja troszke krotsza
UPDATE categories c, ( (SELECT categories_id, ord.categories_order
FROM categories, (SELECT categories_order
FROM categories WHERE categories_order < (SELECT categories_order
FROM categories WHERE categories_id = 6
LIMIT 1 )
ORDER BY categories_order DESC LIMIT 1 ) AS ord
WHERE categories_id = 6)
UNION
(SELECT c1.categories_id, ord.categories_order
FROM categories c1, (SELECT categories_order
FROM categories WHERE categories_id = 6) AS ord
WHERE c1.categories_order < ord.categories_order
ORDER BY c1.categories_order DESC LIMIT 1 )) AS nowe_dane
SET c.categories_order = nowe_dane.categories_order
WHERE c.categories_id = nowe_dane.categories_id