Laravel : QueryBuilder with max(date) - laravel

I want to retrieve all the rows in the database which have a criteres_id to 30. Except that it is a log table, so I have several occurrences with the same products_id. I would like to recover the products_id which has the highest date.
my table :
products_id = 1 date = 10/12/2020
products_id = 2 date = 10/12/2020
products_id = 2 date = 4/10/2020
products_id = 3 date = 9/12/2020
products_id = 3 date = 1/12/2020
I want to take
products_id = 1 date = 10/12/2020
products_id = 2 date = 10/12/2020
products_id = 3 date = 9/12/2020
my request sql :
SELECT MAX( DATE ) , products_id, criteres_value
FROM `products_main_criteres_history`
WHERE `manufacturers_id`
IN ( 263962, 263961 )
AND `criteres_id` =30
GROUP BY products_id
I try to make that :
ProductMainCritereHistory::
select('products_id')
->max('date')
->where('criteres_id', '=', '30')
->where('manufacturers_id', '<', '1000')
->groupBy('products_id')
->get();
thks for your help

here's my solution :
ProductMainCritereHistory::
select('products_id')
->orderBy('date', 'desc')
->where('criteres_id', '=', '30')
->where('criteres_value', '>', '1')
->where('manufacturers_id', '<', '1000')
->groupBy('products_id')
->get();

You can try the given solution query. In this case, you can use groupBy to get the unique record only along with sort by date ascending so you'll get the desired result.
$data = ProductMainCritereHistory::where('criteres_id', '=', '30')
->where('manufacturers_id', '<', '1000')
->orderBy('date','asc')
->groupBy('products_id')
->get();

Related

Laravel search across multiple date ranges

id
listing_id
start_date
end_date
1
1
2023-01-20
2023-01-25
2
1
2023-02-26
2023-02-10
3
1
2023-02-11
2023-02-20
4
1
2023-02-21
2023-02-27
$listings->whereHas(
'availabilityCalendar',
function ($query) use ($start_date, $end_date) {
$query->where('start_date', '>=', $start_date)
->where('end_date', '<=', $end_date);
})
}
Fetch data according to start_date = 2023-01-23 / end_date = 2023-02-20 I sent by frontend. The start_date and end_date values I sent are among the values in the records I wrote above.
If I sent start_date = 2023-01-01 / end_date = 2023-02-20 they wouldn't be included. Or if I had submitted the dates start_date = 2023-01-23 / end_date = 2024-01-01 they would still not be included.
But if I sent the dates start_date = 2023-02-01 / end_date = 2023-02-15 it would have been met.
Can you help with this?
You should make sure your query are casted as date.
You can do some thing like
$startDate = Carbon::createFromFormat('Y-m-d', $start_date);
$endDate = Carbon::createFromFormat('Y-m-d', $end_date);
$query->whereDate('start_date', '>=', $startDate )
->whereDate('end_date', '<=', $endDate );
or
$query->where(DB::raw('DATE(start_date)'), '>=', $startDate )
->where(DB::raw('DATE(end_date)'), '<=', $endDate );

Convert DB::Select to Query Builder

i has raw query in laravel like this
public function getPopularBook(){
$book = DB::select("
with totalReview as(
SELECT r.book_id , count(r.id)
FROM review r
GROUP BY r.book_id
)
SELECT *
from totalReview x
left JOIN (
SELECT b.*,
case when ((now() >= d.discount_start_date and now() <= d.discount_end_date) or (now() >= d.discount_start_date and d.discount_end_date is null)) then (b.book_price-d.discount_price)
ELSE b.book_price
end as final_price
FROM discount d
right JOIN book b
on d.book_id = b.id
) as y
on x.book_id = y.id
ORDER BY x.count DESC, y.final_price ASC
LIMIT 8"
);
return $book;
}
so when i want to return a paginate, it doesn't work so can i convert this to query build to use paginate
This is a very un-optimized raw query in itself. You are performing too many Join in Subquery just to sort by price
i'm assuming the database table:
books[ id, name, price ]
reviews[ id, book_id ]
discounts[ id, book_id, start_date, end_date, discount_price]
Look how easy it is if you just use Eloquent:
Book::withCount('reviews')->orderBy('reviews_count')->get();
this will give you all the Books order by number of reviews
now with the final price, this can be a bit tricky, let's take a look at a query when we don't consider discount time
Book::withCount('reviews')
->withSum('discounts', 'discount_price') //i'm assuming a book can have many discount at the same time, so i just sum them all
->addSelect(
DB::raw('final_price AS (books.price - discounts_sum_discount_price)')
)
->orderBy('reviews_count', 'asc') // =you can specify ascending or descending
->orderBy('final_price', 'desc') //in laravel chaining multiple orderBy to order multiple column
->get();
I dont even need to use Subquery!! But how do we actually only add the "active" discount?, just need to modify the withSum a bit:
Book::withCount('reviews')
->withSum(
[
'discounts' => function($query) {
$query->where('start_date', '<=', Carbon::now())
->where('end_date', '>=', Carbon::now())
}
],
'discount_price'
)
->addSelect(
DB::raw('final_price AS (books.price - discounts_sum_discount_price)')
)
->orderBy('reviews_count', 'asc') // =you can specify ascending or descending
->orderBy('final_price', 'desc') //in laravel chaining multiple orderBy to order multiple column
->get();
and it is done
What about pagination? just replace the get() method with paginate():
Book::withCount('reviews')
->withSum(['discounts' => function($query) {
$query->where('start_date', '<=', Carbon::now())->where('end_date', '>=', Carbon::now())
}],'discount_price')
->addSelect(DB::raw('final_price AS (books.price - discounts_sum_discount_price)')) //just format to be a bit cleaner, nothing had changed
->orderBy('reviews_count', 'asc')
->orderBy('final_price', 'desc')
->paginate(10); //10 books per page
WARNING: this is written with ELoquent ORM, not QueryBuilder, so you must define your relationship first

Fetch records that matches month and year using Laravel eloquent

How do I query a table such that it only fetches records that matches a particular month and year e.g. Y-m i.e. 2020-10. of the 'created_at' column.
This is what I am currently doing:
School::where('user_id', 1)->where('created_at', '=', '2020-10')->count();
I would suggest to create a date range for your filter so this way your query will remain sargable
$date = \Carbon\Carbon::parse($year."-".$month."-01");
$start = $date->startOfMonth()->format('Y-m-d H:i:s');
$end = $date->endOfMonth()->format('Y-m-d H:i:s');
School::where('user_id', 1)
->whereBetween('created_at', [$start, $end])
->count();

search dates with laravel not between query

I have to search for data with given dates and time (morning and evening). How can I find available dates from data with laravel query?
If i search dates 2019-06-10 to 2019-06-18. It should only return id 3 and 4. In this query, it is returning id 1, 3 and 4. What's wrong with this query it is not checking from in between dates? I have date type column in the database for start and end date.
I want to check two conditions
Given dates should be not equal to date_from and date_to
Given dates are not between in these dates
Both conditions in same query. Hope you understand.
id event_id date_from date_to
1 1 2019-06-08 2019-06-12
2 1 2019-06-14 2019-06-16
3 2 2019-06-20 2019-06-25
4 3 2019-07-26 2019-07-27
$getEvents = Booking::where('category_id', '=', $categoryID)
->where('date_from', '!=', $startDate)
->where('date_to', '!=', $endDate)
->orWhere('date_from', '<', $startDate)
->orWhere('date_to', '>', $endDate)
->whereNotBetween('date_from', [$startDate,$endDate])
->whereNotBetween('date_to', [$startDate,$endDate])
->get();
Try this
DB::table('table_name')
->whereNotBetween('date', [star_date, end_date])
->get();
Assuming that $endDate will always be greater (or equal) than $startDate
$startDate = "2019-06-10";
$endDate = "2019-06-18";
Given dates are not between in these dates
->whereDate('date_to', '<', $startDate)
->whereDate('date_from', '>', $endDate)
If given $startDate is greater than db 'date_to', $startDate is not between 'date_to' and 'date_from'. Will retrieve records with 'date_to' less than "2019-06-10".
And when the given 'date_from' is greater than $endDate, $endDate is not between 'date_to' and 'date_from'. Will retrieve records with 'date_from' greater than "2019-06-18".
Given dates should be not equal to date_from and date_to
This is not needed since in the query of point 2, we use > and <, which will not take into account equals.
//->where('date_from', '<>', $startDate)->where('date_from', '<>', $endDate)
//->where('date_to', '<>', $startDate)->where('date_to', '<>', $endDate)
Just:
$getEvents = Booking::where('category_id', '=', $categoryID)
->whereDate('date_to', '<', $startDate)
->whereDate('date_from', '>', $endDate)
->get();
Laravel 5
$getEvents = Booking::where('category_id', '=', $categoryID)
->where('date_from', '<', $startDate)
->where('date_to', '>', $endDate)
->get();

I Create mysql query but i not get pagination how to use laravel paginate in this query

I've created MySQL query for searching results. The query works properly but if I use laravel pagination on this query I get an error
Call to a member function paginate() on array ,
How to solve this with pagination?
$search = \DB::SELECT("SELECT l.*,
r.id AS reservation_id,
r.status AS res_status,
r.start_date,
r.end_date,
Avg(r.rating) AS rating
FROM listings l
LEFT JOIN reservations r ON r.listing_id = l.id
WHERE ( ( Cast('" . $search_date . "' AS date) NOT BETWEEN r.start_date AND r.end_date ) OR r.status = 'Cancel' )
AND l.city_id = $city_id
AND l.persons >= $guests
AND l.listing_type_id = $type
GROUP BY l.id
ORDER BY r.rating DESC
");
DB::select() will return an array. You could probably convert your query to a Query Builder and then use paginate() on it. For example:
$search = DB::table('listings')
->selectRaw('listings.*, reservations.id AS reservation_id, reservations.status AS res_status, reservations.start_date, reservations.end_date, AVG(reservations.rating) as rating')
->leftJoin('reservations', 'reservations.listing_id', 'listings.id')
->whereRaw("(CAST(? AS date) NOT BETWEEN reservations.start_date AND reservations.end_date) or reservations.status = 'Cancel'", [$search_date])
->where('listings.city_id', '=', $city_id)
->where('listings.persons', '>=', $guests)
->where('listings.listing_type_id', '=', $type)
->groupBy('listings.id')
->orderBy('reservations.rating', 'DESC')
->paginate(10);

Resources