*Zarys sytuacji
Wyobraźmy sobie następującą sytuację. Mamy tablicę użytkowników z
przypisaną do każdej osoby aktywnością oznaczającą, przyjmijmy w
uproszczeniu, liczbę logowań danego użytkownika do systemu. Chcemy aby
użytkownik mógł się łatwo dowiedzieć o swoim miejscu w rankingu
aktywności.
*Rozwiązanie nie będące głównym bohaterem tego tekstu
Można do problemu podejść w ten sposób, żeby do tablicy użytkowników
wstawić dodatkowe pole rank i za każdym razem, gdy użytkownik się
loguje, sprawdzać wartość pola activity i porównywać ją z wartością
tego pola u użytkownika o poprzedniej i następnej wartości pola rank.
Jeśli np. pole o poprzedniej wartości pola rank ma pole activity o
większej wartości, pola zamieniają się nawzajem wartością pola rank.
Takie rozwiązanie wymaga jednak ciągłej modyfikacji bazy danych, co
jest mniej optymalne, niż nawet dość złożone zapytanie do bazy danych
jedynie odczytujące informacje. Tym bardziej, jeśli informacja o
pozycji w rankingu będzie odczytywana sporadycznie.
*Rozwiązanie – główy bohater tego tekstu
Chcąc uzyskać informację o pozycji w rankingu mając do dyspozycji
jedynie pole activity, możemy skorzystać z mechanizmu zmiennych
użytkownika (User-Defined Variables), nazywanych w innych źródłach
zmiennymi sesyjnymi (Session Variables), lub, mniej poprawnie,
zmiennymi lokalnymi (Local Variables).
SET @m:=0;
SELECT rank FROM
(SELECT id, activity, @m:=@m+1 AS rank
FROM `users`
ORDER BY activity DESC) AS User
WHERE id = $user_id
*O co tu chodzi
Mechanizm zmiennych użytkownika polega na tym, że najpierw przy pomocy
wyrażenia SET ustalamy wartość początkową zmiennej, a potem odwołujemy
się do niej, lub też modyfikujemy ją w kolejnych zapytaniach do bazy
danych. Zasięg tak utworzonej zmiennej obejmuje okres od uzyskania
połączenia do bazy danych, aż do jego zamknięcia.
Zmienne użytkownika nie wymagają deklaracji (self-defined), co
oznacza, że równie dobrze pierwszy wiersz powyższego przykładu mógłby
wyglądać następująco:
SELECT @m := 0;
*Źródła