I have issue with my query. My sample query is as below
$answers = DB::table('IC2017_AY')
->join('IC2017', 'IC2017_AY.UNITID', '=', 'IC2017.UNITID')
->join('SFA1617_P1', 'IC2017_AY.UNITID', '=', 'SFA1617_P1.UNITID')
->join('cost', 'IC2017_AY.UNITID', '=', 'cost.UNITID')
->join('gpa', 'IC2017_AY.UNITID', '=', 'gpa.UNITID')
->join('enrollment', 'IC2017_AY.UNITID', '=', 'enrollment.UNITID')
->join('major', 'IC2017_AY.UNITID', '=', 'major.UNITID')
->join('preference', 'IC2017_AY.UNITID', '=', 'preference.UNITID')
->select('IC2017_AY.TUITION2 as in_state_tuition','IC2017_AY.FEE2 as in_state_fee','IC2017_AY.TUITION3 as out_state_tuition','IC2017_AY.FEE3 as out_state_fee','IC2017_AY.CHG4AY3 as books_supplies','IC2017_AY.CHG6AY3 as other_expenses','IC2017.ROOMAMT as room_charge','IC2017.BOARDAMT as board_charge','IC2017.RMBRDAMT as combined_charge','SFA1617_P1.SCUGRAD as total_receiving','SFA1617_P1.SCUGFFN as full_time_receiving','SFA1617_P1.UAGRNTN as total_receiving_grant')
->where($where_data);
->get();
but now I want to pass the array of join because joins will be decided at run time something like this
below code is just the example.
$joins = [
['country', 'user_master.country_id', '=', 'country.country_id'],
['city', 'user_master.city_id', '=', 'city.city_id'],
['login_master', 'user_master.user_id', '=',
'login_master.user_id'],
];
How can I do this in laravel 5.8
thanks in advance.!
You can use foreach loop for example:
$joins = [
['country', 'user_master.country_id', '=', 'country.country_id'],
['city', 'user_master.city_id', '=', 'city.city_id'],
['login_master', 'user_master.user_id', '=',
'login_master.user_id'],
];
$answers = DB::table('IC2017_AY')
->join('IC2017', 'IC2017_AY.UNITID', '=', 'IC2017.UNITID')
->join('SFA1617_P1', 'IC2017_AY.UNITID', '=', 'SFA1617_P1.UNITID')
->join('cost', 'IC2017_AY.UNITID', '=', 'cost.UNITID')
->join('gpa', 'IC2017_AY.UNITID', '=', 'gpa.UNITID')
->join('enrollment', 'IC2017_AY.UNITID', '=', 'enrollment.UNITID')
->join('major', 'IC2017_AY.UNITID', '=', 'major.UNITID')
->join('preference', 'IC2017_AY.UNITID', '=', 'preference.UNITID');
foreach($joins as $key=>$value){
$answer = $answer->join(implode(",",$value));
}
return $answer->select('IC2017_AY.TUITION2 as in_state_tuition','IC2017_AY.FEE2 as in_state_fee','IC2017_AY.TUITION3 as out_state_tuition','IC2017_AY.FEE3 as out_state_fee','IC2017_AY.CHG4AY3 as books_supplies','IC2017_AY.CHG6AY3 as other_expenses','IC2017.ROOMAMT as room_charge','IC2017.BOARDAMT as board_charge','IC2017.RMBRDAMT as combined_charge','SFA1617_P1.SCUGRAD as total_receiving','SFA1617_P1.SCUGFFN as full_time_receiving','SFA1617_P1.UAGRNTN as total_receiving_grant')
->where($where_data);
->get();
Related
This is the current code of my joins.
$vehicleTransferNotifications=DB::table('vehicle_transfer_notifications')
->join('vehicle_requests', 'vehicle_transfer_notifications.request_id', '=', 'vehicle_requests.id')
// ->join('users', 'vehicle_requests.users_id', '=', 'users.id')
// ->join('companies', 'users.company_id', '=', 'companies.id')
// ->join('companies', 'vehicle_transfer_notifications.company_id', '=', 'companies.id')
->join('vehicles', 'vehicle_requests.vehicle_id', '=', 'vehicles.id')
->join('companies', 'vehicles.company_id', '=', 'companies.id')
->join('vehicle_types', 'vehicles.vehicle_type_id', '=', 'vehicle_types.id')
->join('vehicle_make', 'vehicles.make_id', '=', 'vehicle_make.id')
->select('vehicle_transfer_notifications.*','vehicle_transfer_notifications.id as notification_id','vehicle_transfer_notifications.seen as is_seen','vehicle_requests.*','vehicles.reg_no','vehicle_types.type','vehicle_make.name','companies.name as company_name')
->where('vehicle_transfer_notifications.company_id','=',auth()->user()->company_id)
->get();
Now I want add something like I have comment in my code.How I add to this join query? Because I have already join my query with companies table so how can I join again with the companies table and get something like companies.name again in the select query?
You should give alias to companies table as per your requirement.
use that alias for fetch data instead of companies
$vehicleTransferNotifications=DB::table('vehicle_transfer_notifications')
->join('vehicle_requests', 'vehicle_transfer_notifications.request_id', '=', 'vehicle_requests.id')
->join('vehicles', 'vehicle_requests.vehicle_id', '=', 'vehicles.id')
->join('companies as company_one', 'users.company_id', '=', 'company_one.id')
->join('companies as company_two', 'vehicle_transfer_notifications.company_id', '=', 'company_two.id')
->join('companies as company_three', 'vehicles.company_id', '=', 'company_three.id')
->join('vehicle_types', 'vehicles.vehicle_type_id', '=', 'vehicle_types.id')
->join('vehicle_make', 'vehicles.make_id', '=', 'vehicle_make.id')
->select('company_one.name as company_name_one', 'company_two.name as company_name_two', 'company_three.name as company_name_three', 'vehicle_transfer_notifications.*','vehicle_transfer_notifications.id as notification_id','vehicle_transfer_notifications.seen as is_seen','vehicle_requests.*','vehicles.reg_no','vehicle_types.type','vehicle_make.name')
->where('vehicle_transfer_notifications.company_id','=',auth()->user()->company_id)
->get();
I'm trying to count how many tickets our operators have closed in a week(and per day) I have these 2 queries
$closedWeek = Ticket::join('activity_log', 'activity_log.rel_id', '=', 'ticket.id')
->where([
['activity_log.created_at', '>', $fri],
['activity_log.user_id', '=', $id],
['activity_log.event_name', '=', 'ticket_closed'],
['number', 'like', 'SD%']
])->count();
$closedWeek2 = Ticket::join('activity_log', 'activity_log.rel_id', '=', 'ticket.id')
->where([
['activity_log.created_at', '>', $fri],
['activity_log.user_id', '=', $id],
['number', 'like', 'SD%'],
['activity_log.event_name', '=', 'ticket_department_updated']
])
->where(function($query) {
$query->where('activity_log.new_value', '=', 'closed Uninvoiced')
->orWhere('activity_log.new_value', '=', 'To Invoice')
->orWhere('activity_log.new_value', '=', 'closed Other')
->orWhere('activity_log.new_value', '=', 'closed Invoiced');
})->count();
$closedWeek = $closedWeek + $closedWeek2;
They are bringing back slightly bigger numbers than expected and I think some of them are duplicated. How could I put these into one query using where(function($query)) or do I have to use DB::raw instead? I can then count unique ids
You can use GroupBy(); with id,
Example:
$closedWeek = Ticket::join('activity_log', 'activity_log.rel_id', '=', 'ticket.id')
->where([
['activity_log.created_at', '>', $fri],
['activity_log.user_id', '=', $id],
['activity_log.event_name', '=', 'ticket_closed'],
['number', 'like', 'SD%']
])
->groupBy('ticket.id')
->count();
$closedWeek2 = Ticket::join('activity_log', 'activity_log.rel_id', '=', 'ticket.id')
->where([
['activity_log.created_at', '>', $fri],
['activity_log.user_id', '=', $id],
['number', 'like', 'SD%'],
['activity_log.event_name', '=', 'ticket_department_updated']
])
->whereIn('activity_log.new_value',
[ 'closed Uninvoiced',
'To Invoice',
'closed Other',
'closed Invoiced',
])
->groupBy('ticket.id')
->count();
$closedWeek = $closedWeek + $closedWeek2;
OBS:
You dont need '=', on equal wheres, example, where('colun', '=', 'abc'); you can change to where('colun', 'abc');
Please test and see if you have the expected result.
References:
How to get distinct values for non-key column fields in Laravel?
I am building a query which will be executed every minute when the daily_at time and the current time are equal. The daily_at variable is a timestamp of for example 10:05:33.
I want the where clause in the query to pass when the hour and minute are the same, but not the second else almost non will be executed. The where clause which I have now:
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::now()->toTimeString())
.....
Could someone help me to adjust the where clause to ignore the seconds?
Try with:
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::now()->format('H:i'))
One more way:
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::createFromTime(Carbon::now()->hour,Carbon::now()->minute,00)->format('H:i:s'))
You can pass an extra argument to set timezone:
Carbon::createFromTime(Carbon::now()->hour,Carbon::now()->minute,00,'Example/Zone')->format('H:i:s')
I found the solution. You can use setSeconds(int $value) method:
Carbon::now()->setSeconds(0)->toTimeString()
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::now('Y-m-d H:i')->toTimeString())
use this code
Can you please try with this way:
whereRaw(DATE_FORMAT(daily_at, "%H:%i") = Carbon::now()->format('H:i'))
So final query would be,
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::now()->toTimeString())
->whereRaw(DATE_FORMAT(daily_at, "%H:%i") = Carbon::now()->format('H:i'))
is there any way to make these queries shorter or simpler? or maybe get the result in 1 query rather than 3.??
any advise appreciated
$room_single = \DB::table('book_room')
->leftJoin('book_tour', 'book_room.bookingID', '=', 'book_tour.bookingID')
->where('tourdateID', '=', $id)
->where('roomtype','=',1)
->where('book_room.status','=',1)
->count();
$room_double = \DB::table('book_room')
->leftJoin('book_tour', 'book_room.bookingID', '=', 'book_tour.bookingID')
->where('tourdateID', '=', $id)
->where('roomtype','=',2)
->where('book_room.status','=',1)
->count();
$room_triple = \DB::table('book_room')
->leftJoin('book_tour', 'book_room.bookingID', '=', 'book_tour.bookingID')
->where('tourdateID', '=', $id)
->where('roomtype','=',3)
->where('book_room.status','=',1)
->count();
$total= $room_single+($room_double*2)+($room_triple*3) ;
In this case, since the roomtype column relates directly to how you would calculate the total you could just use sum instead of count:
$total = \DB::table('book_room')
->leftJoin('book_tour', 'book_room.bookingID', '=', 'book_tour.bookingID')
->where('tourdateID', '=', $id)
->where('book_room.status', '=', 1)
->sum('roomtype');
UPDATE
If you still need the count for each roomtype then you could do something like:
$query = \DB::table('book_room')
->leftJoin('book_tour', 'book_room.bookingID', '=', 'book_tour.bookingID')
->where('tourdateID', '=', $id)
->where('book_room.status', '=', 1);
$room_single = $query->newQuery()->where('roomtype', 1)->count();
$room_double = $query->newQuery()->where('roomtype', 2)->count();
$room_triple = $query->newQuery()->where('roomtype', 3)->count();
$total = $room_single + ($room_double * 2) + ($room_triple * 3);
Using newQuery means that you can reuse constraints without adding to the original.
Or if you don't want to make multiple queries and you want php to handle the counts
$rooms = \DB::table('book_room')
->select('roomtype')
->selectRaw('count(*) as room_count')
->leftJoin('book_tour', 'book_room.bookingID', '=', 'book_tour.bookingID')
->where('tourdateID', '=', $id)
->where('book_room.status', '=', 1)
->whereBetween('roomtype', [1, 3])//This is only needed if you have other room types
->groupBy('roomtype')
->orderBy('roomtype')
->get('roomtype');
list($room_single, $room_double, $room_triple) = $rooms->pluck('room_count')->toArray();
$total = $rooms->sum(function ($item) {
return $item->room_count * $item->roomtype;
});
Hope this helps!
I dont have enough contributions that is why am posting as answer.
try
GROUP BY roomtype
Then you will not need to change your roomtype.
You can do it in more simple way.
one is,
$query = \DB::table('book_room')
->leftJoin('book_tour', 'book_room.bookingID', '=', 'book_tour.bookingID')
->where('tourdateID', '=', $id)
->where('book_room.status','=',1);
$room_single = $query->where('roomtype','=',1)->count();
$room_double = $query->where('roomtype','=',2)->count();
$room_triple = $query->where('roomtype','=',3)->count();
And then add these as you want. This is just reducing your lines of code.
Another and better way is following.
$all_type = \DB::table('book_room')
->leftJoin('book_tour', 'book_room.bookingID', '=', 'book_tour.bookingID')
->where('tourdateID', '=', $id)
->where('book_room.status','=',1)
->select('roomtype',\DB::raw('COUNT(bookingID) as count'))
->groupBy('roomtype')
->get();
With this query you will get three count for each room type.
Hope you understand.
$query = new TableA;
$query = $query->join('tableB', 'tableA.b_id', '=', 'tableB.id');
$query = $query->where('tableB.something', '=', '1');
$query = $query->where('tableA.something_else', '=', '2');
And it produces:
WHERE something=1 AND something_else=2 AND .. AND....
BUT now - I need this:
WHERE something=1 AND something_else=2 AND (city=city1 OR city=city2 OR city=city3) AND (country=country1 OR country=country2)
Any ideas?
Make use of Advanced Wheres. For your example, it'd be something like this:
->where(function ($query) {
$query->where('city', '=', city1)
->orWhere('city', '=', city2)
->orWhere('city', '=', city3);
})->where(function ($query) {
$query->where('country', '=', country1)
->orWhere('country', '=', country2);
});
Quick method. Read about raw expressions:
http://laravel.com/docs/queries#raw-expressions