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`);