[MySQL][PHP] Jak stworzyć indeks pierwszych liter dla wybranej kolumny z tabeli, np. A, C, D, H, Z?
Chcesz stworzyć mechanizm, który sam wykona indeks pierwszych liter dla danej kolumny.
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.