Wyświetlenie jednego recordu z jednej tabeli i wszystkich z innej

0

Okej, więc mam tabele albums, artists oraz songs.
albums: id, AlbumTitle, ArtistsId, Year.
artists: id, ArtistName.
songs: id, Title, ArtistId, AlbumId.

Najpierw miałem kod który wyświetla informacje o jednym albumie (w $TB_Albums,TB_Artists są nazwy tabel)

    $id = 5; // np.
    $querySelectAlbums = "SELECT 
              $TB_Albums.AlbumTitle, $TB_Albums.Year,
              $TB_Artists.ArtistName
            FROM $TB_Albums
            INNER JOIN $TB_Artists
              ON $TB_Albums.ArtistId = $TB_Artists.Id
            WHERE $TB_Albums.Id = '$id';"; 
//..
    $res = mysqli_query($link, $querySelectAlbums);
    while ($mfa = mysqli_fetch_assoc($res)) {
      wyswietlInfoOAlbumie($mfa);
    }

I to działało.
Teraz do tego chciałem wyświetlić pod "info o albumie" wszystkie piosenki w albumie. Zrobiłem więc coś takiego:

    $querySelectAlbum = "SELECT 
              $TB_Songs.Id, $TB_Songs.Title, $TB_Songs.Genre, $TB_Songs.Length,  
               $TB_Songs.ArtistId,  $TB_Songs.AlbumId, $TB_Songs.YoutubeId,
              $TB_Albums.AlbumTitle, $TB_Albums.Year, $TB_Albums.CoverPath,
              $TB_Artists.ArtistName
            FROM $TB_Songs
            JOIN $TB_Albums
              ON $TB_Albums.Id = $TB_Songs.AlbumId
            JOIN $TB_Artists
              ON $TB_Artists.Id = $TB_Songs.ArtistId
            WHERE $TB_Songs.AlbumId = '$id'";
  $showedInfo = false;
  while ($mfa = mysqli_fetch_assoc($res)) {  // spodziewam sie wielu rekordów, chce wyciągnąć 1 raz info o albumie z jednego,
    if (!$showrdInfo) {                     // a potem po kolei wszystkie info o piosenkach
      wyswietlInfoOAlbumie($mfa);  // this should invoke once
      $showInfo = true;
    }
    showOneSong($mfa); // this should invoke multiple times
  }

I teraz ten drugi sposób też działa, ale tylko dla albumów w których są jakieś piosenki. Jeżeli w tabeli songs nie ma żadnej piosenki która ma odpowiadający album (żadna nie spełnia warunku songs.AlbumId == albums.id) to nie zwraca też żadnego rekordu z którego mógłbym wyciągnąć info o albumie. Jak to naprawić?

Nie mam pomysłu jak napisać to zapytanie tak żeby dostać zawsze: nazwę albumu, nazwę wykonawcy albumu (z tabel albums i artists) oraz jeżeli jakieś są nazwę piosenki, rok piosenki (z tabeli piosenki).
Informacje o piosence chcę wyświetlić w formie listy, a informacje o albumie raz w formie nagłówka (w załączniku o co mi chodzi).

Nie wiem też czy dobrze jest starać się to zrobić w jednym zapytaniu, czy może napisać jedno dla informacji o albumie a drugie dla listy piosenek?

1

To powinno zawsze pokazać album i autora a piosenki tylko jeżeli będą :

SELECT 
              $TB_Songs.Id, $TB_Songs.Title, $TB_Songs.Genre, $TB_Songs.Length,  
               $TB_Songs.ArtistId,  $TB_Songs.AlbumId, $TB_Songs.YoutubeId,
              $TB_Albums.AlbumTitle, $TB_Albums.Year, $TB_Albums.CoverPath,
              $TB_Artists.ArtistName
            FROM $TB_Songs
            RIGHT JOIN $TB_Albums
              ON $TB_Albums.Id = $TB_Songs.AlbumId
            JOIN $TB_Artists
              ON $TB_Artists.Id = $TB_Songs.ArtistId
            WHERE $TB_Songs.AlbumId = '$id'";
  

Pozdrawiam
paweld

0

Twoje rozwiązanie daje podobny efekt do poprzedniego. Tzn wszystko jest ładnie jeżeli chcę pokazać album który ma w sobie jakieś piosenki (tzn w tabeli songs są recordy które mają pole AlbumId odnoszące się do albumu który chcę pokazać). Ale jeżeli nie ma żadnej piosenki, nic się nie wyświetla. Chciałbym uzyskać coś w stylu

Wyszukanie albumu o id=1;
oczekiwany efekt: (jeżeli piosenki są)

AlbumId | AlbumName | SongId | SongTitle |
--------+-----------+--------+-----------+
      1 |    album1 |      1 |     song1 |
      1 |    album1 |      2 |     song2 |
      1 |    album1 |      3 |     song3 |
      1 |    album1 |      4 |     song4 |
records: 4

lub (jeżeli piosenek nie ma)

AlbumId | AlbumName | SongId | SongTitle |
--------+-----------+--------+-----------+
      1 |    album1 |   null |      null |
records: 1

Zapytanie które podałeś wykonuje pierwszą część, ale jeżeli piosenek nie ma, to nie dostaję żadnego rekordu.

AlbumId | AlbumName | SongId | SongTitle |
--------+-----------+--------+-----------+
records: 0

Chciałbym dostać jeden w którym jest nazwa albumu.

1

Kwestia odpowiedniej kolejności złączeń. Chcesz mieć przede wszystkim albumy, więc od nich zacznijmy.

  SELECT $TB_Albums.AlbumId, $TB_Albums.AlbumName, $TB_Songs.SongId, $TB_Songs.SongTitle, $TB_Artists.ArtistsName
  FROM $TB_Albums
    LEFT JOIN  $TB_Songs
      ON $TB_Albums.Id = $TB_Songs.AlbumId
    LEFT JOIN $TB_Artists
      ON $TB_Albums.ArtistId = $TB_Artists.Id
  WHERE $TB_Albums.Id = '$id'";
  
0

Ten sam efekt.
OK > dla albumów które mają piosenkę
0 recordów > dla albumów które nie mają piosenki (powinien być 1)

0

A jest jakieś powiązanie między albumem a wykonawcą? Wcześniej tego nie zauważyłem ale powinno być mniej więcej tak

SELECT 
              $TB_Songs.Id, $TB_Songs.Title, $TB_Songs.Genre, $TB_Songs.LENGTH,  
               $TB_Songs.ArtistId,  $TB_Songs.AlbumId, $TB_Songs.YoutubeId,
              $TB_Albums.AlbumTitle, $TB_Albums.YEAR, $TB_Albums.CoverPath,
              $TB_Artists.ArtistName
            FROM $TB_Songs
            RIGHT JOIN $TB_Albums
              ON $TB_Albums.Id = $TB_Songs.AlbumId
            JOIN $TB_Artists
              ON $TB_Artists.Id = $TB_Albums.ArtistId
            WHERE $TB_Songs.AlbumI

Pozdrawiam
paweld

0

I na końcu warunek WHERE powinien być taki (zamiast tego co się wkleiło):

WHERE $TB_Albums.Id=$ID

Pozdrawiam
paweld

0

Cześć ;-)

http://sqlfiddle.com/#!2/f6d1a/19

Jeżeli dobrze zrozumiałem o co Ci chodzi to właśnie tego szukasz.
Słowo wyjaśnienia:
-Istnieją 4 albumy (id-1, id-2,id-3,id-4)
-Album 3 i 4 nie mają żadnych piosenek.
-Jeżeli wybierzesz album 3 lub 4 (filtr-where) wtedy dostajesz dokładnie to czego oczekujesz. Jeżeli nie nakładasz filtru, to dostajesz wszystkie albumy+piosenki + jeden rekord dla każdego albumu gdzie nie ma piosenki.

Do schematu wrzuciłem Ci kilka zapytań, żebyś mógł zobaczyć różnice w wynikach ;-)

Pozdrawiam ;-)

0

Już działa, to był problem z całym sqlfiddle.
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1