Tworząc raport zawierający określoną liczbę wierszy, dobrym pomysłem jest ich ponumerowanie. Stosując prostą sztuczkę możemy to zrobić bezpośrednio w MySQL, pomijając dodatkową obróbkę danych w edytorze tekstowym lub arkuszu kalkulacyjnym. Wystarczy w tym celu skorzystać ze zmiennych.
Rozwiązanie problemu numerowania wierszy w MySQL jest niezwykle proste. Wystarczy zdefiniować zmienną globalną, która będzie przechowywać licznik i wyświetlić ją jako argument polecenia SELECT
. Może to wyglądać w następujący sposób:
set @row = 0; select @row := @row + 1 as "Lp.", imie, nazwisko from klienci
Niestety, sytuacja zaczyna się komplikować, gdy rozbudujemy zapytanie. Wzbogacając je o złączenia, klauzulę WHERE
oraz sortowania, możemy spodziewać się błędnego numerowania wierszy. Widać to na poniższym przykładzie pobierania danych dotyczących statystyk odwiedzin strony www:
SET @a:=0; SELECT @a:=@a+1 AS "row", IP FROM `stats` st JOIN `sources` so ON st.source_id = st.source_id WHERE st.created_at BETWEEN "2011-01-01 00:000:00" AND "2011-01-01 23:59:59" AND st.IP LIKE "1%" AND st.source_id=1 ORDER BY st.IP
Wynik takiego wywołania będzie następujący:
row IP ------ --------------- 77 100.113.10.222 50 100.113.10.222 23 100.113.10.222 60 104.87.121.89 33 104.87.121.89 6 104.87.121.89 […]
Sposobem na rozwiązanie tego problemu będzie podzapytanie w klauzuli FROM
. Wystarczy umieścić numerowanie wierszy w zewnętrznym zapytaniu i dodać do niego pozostałe interesujące nas kolumny, które będą pobierane z wewnętrznego zapytania, odpowiedzialnego za filtrowanie oraz sortowanie. Zapytanie SQL po modyfikacji może więc wyglądać w następujący sposób:
SET @a:=0; SELECT @a:=@a+1, IP FROM ( SELECT st.IP FROM `stats` st JOIN `sources` so ON st.source_id = st.source_id WHERE st.created_at BETWEEN "2011-01-01 00:000:00" AND "2011-01-01 23:59:59" AND st.IP LIKE "1%" AND st.source_id=1 ORDER BY st.IP ) AS sub
Numerowanie wierszy w wyniku powyższej modyfikacji będzie poprawne:
row IP ------ --------------- 1 100.113.10.222 2 100.113.10.222 3 100.113.10.222 4 104.87.121.89 5 104.87.121.89 6 104.87.121.89 [...]