[MySQL][PHP] Jak stworzyć indeks pierwszych liter dla wybranej kolumny z tabeli, np. A, C, D, H, Z?

0x01 graphic

Chcesz stworzyć mechanizm, który sam wykona indeks pierwszych liter dla danej kolumny.

0x01 graphic

Indeksy z literami możesz robić ręcznie, co jest wygodne, jeżeli wiesz, na jakie litery zaczynają się wyrazy w wybranej kolumnie tabeli. Możesz więc podlinkować poszczególne litery alfabetu, czyli A, B, C, D ... aż do Z. Wtedy klikając na literę zobaczysz np. imiona osób lub nazwiska czy miasta zaczynające się na podaną literę.

Nie zawsze jest to jednak proste, szczególnie gdy zawartość tabeli zmienia się i rekordów nie ma wiele. Zostawienie indeksu z wszystkimi literami może być mylące dla użytkownika, bo klikając na literę F może nie zobaczyć żadnego rekordu, ponieważ np. nie ma województwa zaczynającego się na F lub brakuje pracownika z nazwiskiem na F. Jest to frustrujące i denerwujące.

Rozwiązaniem jest sprawdzenie, na jakie litery zaczynają się rekordy w tabeli i wykonanie "w locie" kompletnego indeksu. Wystarczy zadać do bazy danych odpowiednio skonstruowane pytanie, zobacz:

<?

$sql="SELECT DISTINCT(UPPER(SUBSTRING(imie,1,1)))

FROM pracownicy ORDER BY imie";

$baza = mysql_connect("localhost", "user", "password");

mysql_select_db("baza1",$baza);

$wynik = mysql_query($sql,$baza);

mysql_close($baza);

for ($i=0;$i<mysql_num_rows($wynik);$i++) {

$wiersz = mysql_fetch_row($wynik);

echo "<a href=\"index.php?litera=$wiersz[0]\">$wiersz[0]</a> ";

}

?>

Standardowo łączymy się z przykładową bazą o nazwie baza1, mam w niej tabelę o nazwie pracownicy z polem imie. Pracowników jest niewielu, a mam kaprys zrobienia indeksu liter, od jakich zaczynają się ich imiona...

Cały sekret to pytanie SELECT. Zawiera ono w sobie kilka funkcji. SUBSTRING() wycina pierwszą literę imienia, bo na ich podstawie powstanie indeks. UPPER() zamienia literę na dużą, bo zakładamy, że indeks będzie składał się z wielkich liter (LOWER() tworzy małe litery, gdyby taki zapis był potrzebny).

Aby litery nie powtarzały się wielokrotnie korzystamy z funkcji DISTINCT(). Wtedy nawet gdy mamy Adama, Anne i Andrzeja, pod uwagę wzięte zostanie tylko jedno A - bo duplikaty zostaną usunięte. Na koniec sortujemy litery w kolejności alfabetycznej i wypisujemy je na ekran. Dla moich kilku imion wyglądało to tak:

A B C M W Z

Oczywiście indeks powinien być od razu podlinkowany, aby po kliknięciu można było pokazać tylko te rekordy, które w polu imie zaczynają się na podaną literę. Oto prosty skrypt wyszukujący rekordy na podaną literę dla naszej bazy, musisz go zmienić w zależności od własnych potrzeb:

<?

$litera = $_GET["litera"];

if ($litera<>"") {

$sql="SELECT * FROM pracownicy WHERE imie LIKE '$litera%';";

$baza = mysql_connect("localhost", "user", "password");

mysql_select_db("baza1",$baza);

$wynik = mysql_query($sql,$baza);

mysql_close($baza);

$wierszy = mysql_num_rows($wynik);

$pol = mysql_num_fields($wynik);

for ($i=0;$i<$wierszy;$i++) {

$wiersz = mysql_fetch_row($wynik);

for ($j=0;$j<$pol;$j++) echo $wiersz[$j]." ";

echo "<br>";

}

}

?>

I gotowe - mamy świetny, bardzo funkcjonalny mechanizm. Jedynym minusem jest to, że im więcej funkcji znajduje się w zapytaniu SELECT, tym bardziej obciąża ono serwer gdy rekordów jest wiele. Dlatego tam gdzie liczba danych jest stała i wiesz, jakie litery znajdują się w indeksie, spisz je i wstaw na stałe, bez ciągłego odpytywania bazy danych.