Rozwinięcie poprzedniego ćwiczenia z group concat. Znamy projekt, znamy bazę danych, znamy schemat relacji. Do dzieła.

PS. Z jakichś względów jak za dużo SQLa w Highlight Blocks wrzucam to WordPress zaczyna się buntować (może SQLInjection węszy), z drugiej strony JSON error, więc może to kwestia edytora Gutenberg. Zatem wrzucam kod finalny i niech czytelnik sam to sobie rozłoży na czynniki.

select m.*, 
COALESCE
(
    ( 
    SELECT GROUP_CONCAT(t.tagname) 
    from `tags` as t 
    where t.id in 
        ( 
            SELECT DISTINCT 
            pivot.tag_id 
            FROM `review_tag` as pivot 
            where pivot.review_id in 
                ( 
                    select r.id 
                    from `reviews` as r 
                    where r.movie_id = m.id 
                ) 
        ) 
     GROUP BY 'all'
    )
, "no tags" ) as 'tags' 
from `movies` as m; 

Wyjaśnienie:

  • movie -> hasMany reviews
  • reviews -> belongsTo movie, movie_id
  • reviews ->belongsToMany tags
  • tags ->belongsToMany reviews
  • review_tag – tag_id, review_id

Tłumaczyliśmy o co chodzi poprzednio, teraz to rozwinięcie tego ćwiczenia. Natomiast WordPress coś mi ostatnio głupieje (odkąd zacząłem wrzucać kody SQLowe, może się boi injection) więc choć chciałem pokazać krok po kroku jak doszliśmy do tego miejsca, pozostawiam ogarnięcie tego czytelnikowi.

Być może chociaż to, na czym stanęliśmy ostatnio przejdzie, zobaczmy:

SELECT 
m.*, 
( 
    SELECT GROUP_CONCAT(t.tagname) 
    from `tags` as t 
    where t.id in 
    ( 
        SELECT DISTINCT 
        pivot.tag_id 
        FROM `review_tag` as pivot 
        where pivot.review_id in 
        ( 
            select r.id 
            from `reviews` as r 
            where r.movie_id = 2 
        ) 
    ) 
    GROUP BY 'all'
) as 'tags'  
from `movies` as m 
where m.id = 2; 

Jak ten „implode” działa to polecam wywalić subquery i odpalić jako query normalne (bez movies). Ta sama baza danych, te same relacje, ten sam projekt.

PS. To jest typowa relacja hasManyThroughMany. Czyli w sumie nie ma takiej relacji w Laravelu, ale może można ją do modelu dopisać, co spróbuję zrobić i na tym blogu opisać, jeśli się da.

Znamy relację hasOneOfMany, będziemy musieli poznać jeszcze hasOneThrough oraz hasManyThrough. Aż takie trudne nie są, bez obaw.