Kontynuujemy poznawanie Laravela. Wreszcie przyda nam się migracja z Movies i Reviews, którą utworzyliśmy jakiś czas temu. Do dzieła.

Ok, przechodzimy do console, importujemy modele, piszemy pierwszą komendę:

Artisan::command('review-count', function () {

    $cnt = Review::count();
    $this->comment("Number of reviews: {$cnt}");
    
});

Teraz fasada DB:

Artisan::command('review-count-db', function () {

    $cnt = DB::table('reviews')->count();
    $this->comment("Number of reviews: {$cnt}");
    
});

Teraz to samo dla filmów:

Artisan::command('movie-count', function () {

    $cnt = Movie::count();
    $this->comment("Number of movies: {$cnt}");
    
});

Artisan::command('movie-count-db', function () {

    $cnt = DB::table('movies')->count();
    $this->comment("Number of movies: {$cnt}");
    
});

Teraz minimalna ocena:

Artisan::command('review-min-rating', function () {

    $min = Review::min('rating');
    $this->comment("Minimum rating: {$min}");
    
});

Fasada db:

Artisan::command('review-min-rating-db', function () {

    $min = DB::table('reviews')->min('rating');
    $this->comment("Min rating: {$min}");
    
});

Maksymalna ocena:

Artisan::command('review-max-rating', function () {

    $max = Review::max('rating');
    $this->comment("Max rating: {$max}");
    
});

Teraz fasada DB:

Artisan::command('review-max-rating-db', function () {

    $max = DB::table('reviews')->max('rating');
    $this->comment("Max rating: {$max}");
    
});

Teraz zrobimy coś ciekawego:

Artisan::command('review-max-rating-2', function () {

    $max = Review::max('rating');

    $numberOfMaxReviews = Review::where('rating', $max)->count();

    $this->comment("Max rating: {$max}");
    $this->comment("Number of reviews with max rating: {$numberOfMaxReviews }");
});

To samo dla min:

Artisan::command('review-min-rating-2', function () {

    $min = Review::min('rating');
    
    $numberOfMinReviews = Review::where('rating', $min)->count();

    $this->comment("Minimum rating: {$min}");
    $this->comment("Number of reviews with minimal rating: {$numberOfMinReviews }");
    
});

Jak to zrobić w SQL? Od razu widzimy, że mamy tutaj jakby jeden select i drugi select. I ten pierwszy jest mniejszy i jego wynik jest elementem warunku drugiego.

Ok, spróbujmy min rating:

SELECT min(rating) 
from `reviews`; 

Ok, max rating:

SELECT max(rating) as max_rating
from `reviews`; 

Ok, policzmy recenzje:

SELECT COUNT(rating)
from `reviews`

W zasadzie w count mogłaby być gwiazdka, ale zbierzmy do kupy te trzy selecty. Jeszcze raz rzut oka na kod.

Mamy taki mini select, który pobiera minimalną wartość recenzji i taki duży select, który wrzuca tamtą wartość w swój warunek. Oczywiście dla Laravela to są dwa oddzielne selecty, bo tam można do zmiennej zapisać, nie myślmy że ->toSql nam pomoże.

Ale idea jest prosta – zaciągnij mini selectem wartość minimalną i wrzuć w warunek dużego selecta. Może zadziała nam ta logika?

SELECT COUNT(rating)
from `reviews`
where rating = (SELECT min(rating) from `reviews`); 

Działa. Teraz na max recenzje:

SELECT COUNT(rating)
from `reviews`
where rating = (SELECT max(rating) from `reviews`); 

Działa. Nadajmy tylko przyjazny alias:

SELECT COUNT(rating) as "max rating number of reviews:"
from `reviews`
where rating = (SELECT max(rating) from `reviews`);