Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]5 ostatnich rekordów (po jednym z tabeli)
Forum PHP.pl > Forum > Przedszkole
-Obcy-
Witam.
Ostatnio napisałem prosty system newsów, wszystko jest ok ale...
Mam pięć 'kategorii' newsów rozmieszczonych w tabelach odpowiadających kategorii.
Na podstronie danej kategorii wyświetlam 10 ostatnich...
Ale chciałbym na stronie głównej umieścić 5 ostatnich ogólnie, czyli ze wszystkich kategorii.

Myślałem, żeby zrobić po prostu:
ostatni z 1 kat.
ostatni z 2 kat.
ostatni z 3 kat.
ostatni z 4 kat.
ostatni z 5 kat.

Ale to odpada bo jest to dosyć 'sztywne' i w ogóle nie o to chodzi. Dodając 5 newsów do kat. 3 (do reszty nic) na głównej powinno wyświetlić się te 5 nowo dodanych.

PS. Pisząc posta wpadłem na pomysł smile.gif (Forum pomaga samo z siebie bez interwencji użytkowników biggrin.gif )
Można przecież wszystkie newsy upakować w jednej tabeli i stworzyć kolumnę 'kategoria'. Później przy pobieraniu tych 5-ciu darować sobie WHERE i jest 5 ostatnich smile.gif
A przy pobieraniu rekordów dla danej kategorii zastosować:
  1. $kategoria = 'kategoria1';
  2.  
  3. (...)WHERE kategoria = '$kategoria' (...)


Czy dobrze kombinuję? ;> A może jakiś lepszy i wydajniejszy sposób znacie?
bostaf
Bardzo dobrze, ale to dopiero początek kombinowania wink.gif Tak było 20 lat temu, tzn. jeden news można dopasować do jednej kategorii. Teraz kategorie nazywa się tagami i do jednego newsa/postu/artykułu przypisuje się dowolną ilość kategorii/tagów. Potrzebujesz 3 tabele:
  1. newsy
    Pola: id_newsa, tresc, autor, data_dodania, data_modyfikacji
  2. kategorie
    Pola: id_kategoria, nazwa
  3. news_kategoria
    Pola: id_newsa, id_kategoria

Ta trzecia tabela służy do łączenia (za pomocą identyfikatorów) newsów z kategoriami/tagami.
Żeby wyciągnąć z tabeli 5 ostatnich newsów sortujesz po dacie malejąco; ORDER BY `data_dodania` DESC LIMIT 5.
-Obcy-
Czy dobrze rozumiem logikę?

Dodaję newsa wybierając kategorię1

W tabeli 'newsy' wszystko ląduje na swoje miejsce (pomijając datę modyfikacji - ty jest pusto)
Jednocześnie do tabeli 'news_kategoria' ląduje takie samo id_newsa jak w tabeli 'newsy' oraz id_kategoria takie samo jak w tabeli 'kategorie'

Ale jak odwołać się do tych 3 tabel?
bostaf
Cytat(-Obcy- @ 8.10.2012, 21:18:10 ) *
Czy dobrze rozumiem logikę?

Dodaję newsa wybierając kategorię1

W tabeli 'newsy' wszystko ląduje na swoje miejsce (pomijając datę modyfikacji - ty jest pusto)
Jednocześnie do tabeli 'news_kategoria' ląduje takie samo id_newsa jak w tabeli 'newsy' oraz id_kategoria takie samo jak w tabeli 'kategorie'

Tak. Dokładnie tak.
Dodając newsa możesz wybrać nawet więcej niż jedną kategorię, ale to nie jest wymóg. Brak kategorii też powinien być dopuszczalny. Powinna być po prostu możliwość edytowania kategorii (np dla admina albo moderatorów albo autora newsa).

Cytat(-Obcy- @ 8.10.2012, 21:18:10 ) *
Ale jak odwołać się do tych 3 tabel?

Trzeba je łączyć składnią językową JOIN. Na przykład, żeby pobrać 2 ostatnie newsy posortowanye po dacie malejąco, razem ze wszystkimi kategoriami, do których każdy jest przypisany:
  1. SELECT
  2. n.id_newsa,
  3. n.tytul,
  4. CONCAT_WS(',', k.nazwa) AS kategorie
  5. FROM newsy n
  6. LEFT JOIN news_kategoria nk ON nk.id_newsa = n.id_newsa
  7. LEFT JOIN kategoria k ON k.id_kategoria = nk.id_kategoria
  8. ORDER BY n.data_dodania DESC
  9. LIMIT 2

W wyniku można dostać coś takiego:
Kod
id_newsa | tytul                          | kategorie
---------+--------------------------------+--------------------------
     123 | Mój sto dwudziesty trzeci news | komputery,nauka
       2 | Teścik                         | testy,programowanie,mysql

A taki wynik można elegancko obrobić w PHP.
JOINy są dla niektórych na początku trudne do ogarnięcia, zwłaszcza że jeden cel można czasami osiągnąć kilkoma sposobami, ale trening czyni mistrza ;)
-Obcy-
  1. SELECT
  2. n.id_newsa,
  3. n.tytul,
  4. CONCAT_WS(',', k.nazwa) AS kategorie
  5. FROM newsy n
  6. LEFT JOIN news_kategoria nk ON nk.id_newsa = n.id_newsa
  7. LEFT JOIN kategoria k ON k.id_kategoria = nk.id_kategoria
  8. ORDER BY n.data_dodania DESC
  9. LIMIT 2


Czyli: Wybieram id_newsa i tytul z tabeli 'newsy' dla których przypisana jest kolumna 'nazwa' z tabeli 'kategorie'.
Dla tabeli 'newsy' przypisuję alians(?) 'n', dla 'kategoria' alians 'k', a alians 'nk' to tabela 'news_kategoria'.

  1. LEFT JOIN news_kategoria nk ON nk.id_newsa = n.id_newsa

Tutaj przypisuję 'nk' dla 'news_kategoria', w której kolumna 'id_newsa' z tabeli 'nk' przyjmuje tą samą wartość co 'id_newsa' z tabeli 'news'.

  1. LEFT JOIN kategoria k ON k.id_kategoria = nk.id_kategoria

Tutaj podobnie jak wcześniej. 'id_kategoria' z tabeli 'kategorie' = 'id_newsa' z tabeli 'news_kategoria'.

Mogę się mylić bo to tylko moja analiza kodu.
Mam nadzieję, że dobrze to rozumiem smile.gif
bostaf
Jeśli to był Twój pierwszy kontakt z JOINami i tyle z tego wydedukowałeś to gratulacje. To będzie dla Ciebie małe piwo smile.gif
Te alternatywne nazwy to aliasy.
-Obcy-
Nie rozumiem tylko jednej rzeczy smile.gif

Przy dodawaniu newsa mam:
  1. INSERT INTO posty SET tytul='$tytul', tresc='$tresc', autor='$autor'
  2. CONCAT_WS(',', k.nazwa) AS kategorie
  3. FROM posty n
  4. LEFT JOIN news_kategoria nk ON nk.id_newsa = n.id_newsa
  5. LEFT JOIN kategoria k ON k.id_kategoria = nk.id_kategoria


Newsa dodaje ale nie wiem jak wykorzystać w tym zapytaniu tabele kategoria.
Chodzi mi dokładnie o tę parę:
  1. LEFT JOIN kategoria k ON k.id_kategoria = nk.id_kategoria


Jak wybrać nazwę kategorii, sprawdzić jej id i włączyć je do powyższego?
bostaf
Składni INSERT używa się w inny sposób:

INSERT INTO nazwa_tabeli [(nazwa_kolumny [, nazwa_kolumny, ...])] VALUES (dane, dane, ...)

Nazwy kolumn w nawiasie, po nazwie tabeli, są opcjonalne, ale warto je precyzować, dla czytelności i na wszelki wypadek, gdyby się w przyszłości kolejność i ilość kolumn w tabeli zmieniła.
Do każdej tabeli INSERTuje się osobno:
  1. INSERT INTO posty(tytul) VALUES ("Tytuł mojego posta"); -- nie wymuszam identyfikatora id_posta, zakładam że to jest AUTO_INCREMENT
  2. SET @id_posta = LAST_INSERT_ID();
  3. INSERT INTO post_kategoria(id_posta, id_kategoria) VALUES (@id_posta, 1), (@id_posta, 3), (@id_posta, 4);

To jeden ze sposobów. W PHP też można bez dodatkowych zapytań sprawdzić wartość ostatnio wygenerowanego auto incrementem identyfikatora. Albo zrobić to dodatkowe zapytanie żeby to sprawdzić. Najlepiej różne opcje ćwiczyć i zobaczyć, z którą się mi najwygodniej pracuje.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.