Echo mysql data using group_concat in PHP

Questo è il mio SQL Fiddle: SQL Fiddle

Sto cercando di echeggiare questo risultato usando PHP. Questo è il mio risultato previsto:

// Some Stuff Here The Dark Knight Rises - 7.5 Batman Begins - 7.5 Iron Man - 7.3 The Lord of the Rings: The Return of the King - 8.1 etc... // Some more Stuff here 

Il mio codice PHP:

 $stmt = $conn->prepare("SELECT tmdb_movies.movie_title ,GROUP_CONCAT(recommendations.recommendations_title ORDER BY recommendations.recommendations_title) as recommendations_title ,GROUP_CONCAT(recommendations.recommendations_vote_average ORDER BY recommendations.recommendations_title) as recommendations_vote_average FROM tmdb_movies LEFT JOIN cast ON cast.cast_tmdb_id=tmdb_movies.tmdb_id LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id Where tmdb_movies.tmdb_id= 155 GROUP BY tmdb_movies.movie_title "); // Then fire it up $stmt->execute(); // Pick up the result as an arrays $result = $stmt->fetchAll(); // Now you run through this arrays in many ways, for example for($x=0, $n=count($result); $x < $n; $x++){ $recommendations_name_list = explode(',',$result[$x]["recommendations_title"]); $recommendations_vote_average = explode(',',$result[$x]["recommendations_vote_average"]); foreach( $recommendations_name_list as $index => $recommendations_title ) { echo' <p>'.$recommendations_title.'- '.$recommendations_vote_average[$index].'</p>'; } } 

Uscita di questo codice:

 Batman Begins- 7.5 Batman Begins- 7.5 Batman Begins- 7.5 Batman Begins- 7.5 Batman Begins- 7.5 Batman Begins- 7.5 Batman Begins- 7.5 Batman Begins- 7.5 Batman Begins- 7.5 Batman Begins- 7.5 Captain America: The First Avenger- 6.6 Captain America: The First Avenger- 6.6 Captain America: The First Avenger- 6.6 Captain America: The First Avenger- 6.6 Captain America: The First Avenger- 6.6 Captain America: The First Avenger- 6.6 Captain America: The First Avenger- 6.6 Captain America: The First Avenger- 6.6 Captain America: The First Avenger- 6.6 Captain America: The First Avenger- 6.6 Inception- 8 Inception- 8 Inception- 8 Inception- 8 Inception- 8 Inception- 8 Inception- 8 Inception- 8 Inception- 8 Inception- 8 Iron Man- 7.3 Iron Man- 7.3 Iron Man- 7.3 Iron Man- 7.3 Iron Man- 7.3 Iron Man- 7.3 Iron Man- 7.3 Iron Man- 7.3 Iron Man- 7.3 Iron Man- 7.3 Iron Man 2- 6.6 Iron Man 2- 6.6 Iron Man 2- 6.6 Iron Man 2- 6.6 Iron Man 2- 6.6 Iron Man 2- 6.6 Iron Man 2- 6.6 Iron Man 2- 6.6 Iron Man 2- 6.6 Iron Man 2- 6.6 The Dark Knight Rises- 7.5 The Dark Knight Rises- 7.5 The Dark Knight Rises- 7.5 The Dark Knight Rises- 7.5 The Dark Knight Rises- 7.5 The Dark Knight Rises- 7.5 The Dark Knight Rises- 7.5 The Dark Knight Rises- 7.5 The Dark Knight Rises- 7.5 The Dark Knight Rises- 7.5 The Lord of th- 8 

Ma se rimuovo questa linea, LEFT JOIN cast ON cast.cast_tmdb_id=tmdb_movies.tmdb_id , allora, il mio codice php funziona LEFT JOIN cast ON cast.cast_tmdb_id=tmdb_movies.tmdb_id .

Risultato atteso:

 Batman Begins- 7.5 Captain America: The First Avenger- 6.6 Inception- 8 Iron Man- 7.3 Iron Man 2- 6.6 The Dark Knight Rises- 7.5 The Lord of the Rings: The Fellowship of the Ring- 8 The Lord of the Rings: The Return of the King- 8.1 The Lord of the Rings: The Two Towers- 7.9 The Matrix- 7.9 

L'uso del LEFT JOIN cast
è inutile per i valori selezionati (i risultati sono selezionati perché sono basati sulla tabella maun movie_title adn non restituiscono informazioni utili perché non ci sono colonne da di table nella clausola select) e producono un set risultante con più righe

quindi se vuoi insistere sul join sinistro puoi aggiungere DISTINCT alla tua query originale

  SELECT DISTICNT tmdb_movies.movie_title ,GROUP_CONCAT(recommendations.recommendations_title ORDER BY recommendations.recommendations_title) as recommendations_title ,GROUP_CONCAT(recommendations.recommendations_vote_average ORDER BY recommendations.recommendations_title) as recommendations_vote_average FROM tmdb_movies LEFT JOIN cast ON cast.cast_tmdb_id=tmdb_movies.tmdb_id LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id Where tmdb_movies.tmdb_id= 155 GROUP BY tmdb_movies.movie_title 

o meglio non usare il cast pn di join sinistro

  SELECT tmdb_movies.movie_title ,GROUP_CONCAT(recommendations.recommendations_title ORDER BY recommendations.recommendations_title) as recommendations_title ,GROUP_CONCAT(recommendations.recommendations_vote_average ORDER BY recommendations.recommendations_title) as recommendations_vote_average FROM tmdb_movies LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id Where tmdb_movies.tmdb_id= 155 GROUP BY tmdb_movies.movie_title 

Molte delle cose che hai nel tuo post non si sumno. Il tuo sql fiddle manca completamente al tavolo del cast. Ho già commentato che stai usando GROUP_CONCAT in modo inappropriato. La tua domanda non ha le informazioni complete per aiutarci a capire il tuo problema.

Detto questo, credo di aver ipotizzato qualcosa di simile a ciò che realmente volevi. Il problema principale è che il tuo GROUP BY dovrebbe includere sia il film originale che i film consigliati. Ciò ti restituirà una row per combinazione di film / consiglio. Puoi utilizzare GROUP_CONCAT per get il cast in una colonna. Inoltre, penso che i dati del cast che vuoi siano in realtà il cast del film consigliato, non il cast del film originale. Si potrebbe get entrambi insieme, ma nel context di questa query, mi sembra che si vorrebbe il cast del film consigliato assemblato in una colonna con GROUP_CONCAT. Come ti ho commentato, il problema è che non hai il filmato consigliato tmdb_id nella tabella dei consigli. Francamente si tratta di una struttura denormalizzata (che conserva il titolo piuttosto che l'id) ed è relazionalmente scorretta, dispendiosa e potenzialmente confusa.

Perchè è questo?

Prima di tutto, la tabella dei consigli non ha una chiave primaria e ne ha bisogno. Anche il titolo non è un buon candidato, perché ci sono molti film che hanno lo stesso titolo. Con il tuo sistema non c'è modo di determinare quale film tra più titoli possa avere lo stesso titolo. Quindi, quello che dovresti avere, è il tmdb_id come chiave esterna e, a quel punto, non avresti bisogno (né vuoi) del titolo, perché potrebbe essere ottenuto dalla tabella tmdb_movies. La tabella dei consigli è essenzialmente una tabella molti-a-molti che mette in relazione i film tra loro in modo genitore-figlio. A parte le chiavi esterne (tmdb_id, recommended_tmdb_id) in realtà non c'è bisogno che ci sia qualcos'altro nella tabella, dato che i valori attualmente presenti (titolo, valutazione media) sono valori denormalizzati che sono memorizzati nella tabella tmdb_movies.

Ora pensa al futuro, quando forse hai migliaia di film, ognuno dei quali potrebbe avere 10 film consigliati relativi ad esso. Perderai per each film, megabyte di memory del database che ripetono lo stesso titolo e il valore medio che non cambia. Peggio ancora, le medie sono un'istantanea nel tempo. Ogni volta che il rating medio deve essere ricalcolato, piuttosto che aggiornare un singolo valore in una row della tabella tmdb_movie, ora è necessario aggiornare each singola row nel consiglio in cui quel film è stato raccomandato all'originale. Questi sono alcuni dei costi della de-normalizzazione.

Ora alle specifiche di GROUPing.

Prima di illustrare il modo in cui funziona GROUP BY, ti suggerisco di eseguire queste query nel tuo sqlfiddle o live db:

 SELECT tmdb_movies.movie_title, recommendations.recommendations_title, recommendations.recommendations_vote_average FROM tmdb_movies LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id GROUP BY tmdb_movies.tmdb_id, recommendations.recommendations_title Where tmdb_movies.tmdb_id=1 

La cosa fondamentale che è diversa da ciò che hai fatto è che ho rimosso le inutili dichiarazioni GROUP_CONCAT e ho fatto un GROUP BY su tmdb_movies.tmdb_id, recommendations.recommendations_title.

Idealmente questo sarebbe da parte degli id, ma ho spiegato quanto sopra, quindi per ora dobbiamo usare solo il titolo.

Come puoi vedere, ottieni un GRUPPO per each combinazione unica di film e film consigliati. Sembra questo è quello che vuoi. Nota che non ho usato GROUP_CONCAT affatto e ottieni la media e il titolo, uno per row.

Supponiamo ora di voler anche unirti alla tabella del cast.

Aggiungiamolo in:

 SELECT tmdb_movies.movie_title, recommendations.recommendations_title, recommendations.recommendations_vote_average FROM tmdb_movies LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id LEFT JOIN cast ON cast.recommendations_title=recommendations.recommendations_title GROUP BY tmdb_movies.tmdb_id, recommendations.recommendations_title 

Notare che NIENTE CAMBIAMENTI. Non ottieni righe estranee, perché GROUP BY riduce già i duplicati e lascia una row per gruppo, anche se ora stiamo partecipando a film-> raccomandazione-> cast

Quindi, ora presumo che tu voglia il cast in una colonna nel risultato. Qui è where GROUP_CONCAT è effettivamente utile e sembra appropriato:

 SELECT tmdb_movies.movie_title, recommendations.recommendations_title, recommendations.recommendations_vote_average, GROUP_CONCAT(cast.name) FROM tmdb_movies LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id LEFT JOIN cast ON cast.recommendations_title=recommendations.recommendations_title GROUP BY tmdb_movies.tmdb_id, recommendations.recommendations_title 

Ecco lo sqlfiddle di questo :