I am struggling to add a whereIn to a more complex query:
$events = Toolplan::query()
->select('id', 'eventId', 'resourceId', 'title', 'start', 'end')
->where(function ($query) use ($start, $end) {
$query->whereDate('start', '>=', $start)->whereDate('end', '<=', $end);
})
->orWhere(function ($query) use ($start, $end) {
$query->whereDate('start', '<=', $start)->whereDate('end', '>=', $end);
})
->orWhere(function ($query) use ($start, $end) {
$query->whereDate('end', '>=', $start)->whereDate('end', '<=', $end);
})
->orWhere(function ($query) use ($start, $end) {
$query->whereDate('start', '>=', $start)->whereDate('start', '<=', $end);
})
// gives "General error: 1096 No tables used":
->whereIn('eventId', function ($query) use ($eventIds){
$query->whereIn('eventId', $eventIds);
})
// no effect:
// ->whereIn('eventId', $eventIds)
->get();
I tried to add it as a function and in simple form but the function leads to General error: 1096 No tables used and the other shows no effect at all, because the collection is far too large and should be only 4 items after whereIn and the orWhere selection. $eventIds is a flat array:
["P000018","P000054","P000021","P000030"]
Related
I have this query
$t_items_between = TransferItem::whereHas('transfer', function ($query) use($old_until_date, $inventory_id, $old_from_date_interval) {
$query->where('document_date', '>=', $old_from_date_interval);
$query->where('document_date', '<=', $old_until_date);
$query->where('to_inventory_id', $inventory_id);
})
->with(['transfer' => function($query) use($old_until_date, $inventory_id, $old_from_date_interval) {
$query->where('document_date', '>=', $old_from_date_interval);
$query->where('document_date', '<=', $old_until_date);
$query->where('to_inventory_id', $inventory_id);
}
])
->whereIn('item_id', $subset)
->addSelect(['quantity' => TransferItem::selectRaw('sum(quantity)')
->groupBy('item_stock_id')
->from((new TransferItem)->getTable() . ' as ti')
->whereColumn('ti.item_stock_id', (new TransferItem)->getTable() . '.item_stock_id')
])
->get();
So TransferItem is the model of the table transfer_items. transfer_items has 4 columns: id, transfer_id, item_stock_id and quantity.
What I am trying to do is to sum the quantity of each result, grouping by the item_stock_id, but the query above doesn't work. How would I approach it?
try using map
$t_items_between = TransferItem::whereHas('transfer', function ($query) use($old_until_date, $inventory_id, $old_from_date_interval) {
$query->where('document_date', '>=', $old_from_date_interval);
$query->where('document_date', '<=', $old_until_date); $query->where('to_inventory_id', $inventory_id);
})
->with(['transfer' => function($query) use($old_until_date, $inventory_id, $old_from_date_interval) {
$query->where('document_date', '>=', $old_from_date_interval);
$query->where('document_date', '<=', $old_until_date); $query->where('to_inventory_id', $inventory_id);
}
])
->whereIn('item_id', $subset)
->get()
->groupBy('item_stock_id')
->map(function ($q) {
return $q->sum('quantity');
});
Visit https://laravel.com/docs/9.x/collections
$q = Order::select(
'orders.*',
'items.date_start',
'items.date_end',
'items.location_name',
'items.category_id'
)
->join('items', 'items.item_id', '=', 'orders.item_id')
->leftJoin('orders_items', function ($join) use ($user_id)
{
$join->on('orders_items.order_id', '=', 'orders.order_id')
->on('orders_items.item_id', '=', 'orders.item_id')
->where('orders_items.user_id', '=', $user_id);
})
->with('Items')
->where(function ($query) use ($select_balance) { // This is where event is in the future, or it has a balance and is not draft.
$query->where('items.date_end', '>=', Carbon\Carbon::now()->toDateString())
->orWhere(function ($query) use ($select_balance) {
$query->where(DB::raw($select_balance), '>', 0)
->whereNotIn('orders.status', [0, 79]);
});
});
i would like to set a condition if (date_start == date_end) then
$query->where('items.date_end', '>=', Carbon\Carbon::now()->toDateString())
->orWhere(function ($query) use ($select_balance) {
$query->where(DB::raw($select_balance), '>', 0)
->whereNotIn('orders.status', [0, 79]);
});
else
$query->where('items.date_end', '>', Carbon\Carbon::now()->toDateString())
->orWhere(function ($query) use ($select_balance) {
$query->where(DB::raw($select_balance), '>', 0)
->whereNotIn('orders.status', [0, 79]);
});
how to set a condition within query i try to end query after ->with(items) but that say $q-> has syntax error please guide and explain how to over come this issue
You can use conditional clauses: https://laravel.com/docs/5.5/queries#conditional-clauses
Animals::when($condition, function($query) {
$query->where('size', 'big');
})->when(!$condition, function($query)) {
$query->where('size', 'small');
})->get();
In the example, if $condition is true then we fetch big animals, otherwise we fetch small animals.
I'm struggling to understand how to use Eloquent/Query Builder with relationships.
I have the following:
$plantLots = PlantLot::with('controlNumber')
->whereHas('controlNumber', function ($q) use ($fromDate, $toDate) {
$q->where('created_at', '>=', $fromDate);
if($toDate != '') {
$q->where('created_at', '=<', $toDate);
}
$q->groupBy('creator_id');
})->get();
I want to group by creator_id, but I still just get a single collection of data.
What am I doing wrong?
change it to
$plantLots = PlantLot::with(['controlNumber' => function($q){
$q->groupBy('creator_id');
}])
->whereHas('controlNumber', function ($q) use ($fromDate, $toDate) {
$q->where('created_at', '>=', $fromDate)
->when($toDate != '',function($q){
$q->where('created_at', '=<', $toDate);
});
})->get();
Hope it helps.
I'm creating calendar for few days events and the events can not overlap. But event can start/end when another event starts/ends.
In Laravel, in my event model table I am storing start and end date of events.
How can I check before storing new event do database, if it is valid (is not overlapping with existing events, excluding margin/boundary days) ?
In advance thank You very much for Your help.
You can use following code to get the correct counts for events booked between certain times:
$eventsCount = Events::where(function ($query) use ($startTime, $endTime) {
$query->where(function ($query) use ($startTime, $endTime) {
$query->where('start', '>=', $startTime)
->where('end', '<', $startTime);
})
->orWhere(function ($query) use ($startTime, $endTime) {
$query->where('start', '<', $endTime)
->where('end', '>=', $endTime);
});
})->count();
Use it for all variants intersections date ranges. It help for me
$rangeCount = TransferSchedule::where(function ($query) use ($from, $to) {
$query->where(function ($query) use ($from, $to) {
$query->where('date_from', '<=', $from)
->where('date_to', '>=', $from);
})->orWhere(function ($query) use ($from, $to) {
$query->where('date_from', '<=', $to)
->where('date_to', '>=', $to);
})->orWhere(function ($query) use ($from, $to) {
$query->where('date_from', '>=', $from)
->where('date_to', '<=', $to);
});
})->count();
This is just some pseudocode since you don't provide any code or your model, but depending on how your table is set up, you should be able to do it like this. This will return any events where the new event's start time or end time falls between an existing event's start and end times. This will work if your times are timestamps, or DateTime columns.
Events::where(DB::raw("? between start_time and end_time",$start))
->orWhere(DB::raw("? between start_time and end_time",$end))
->get();
->where(function ($query) use($startDate, $endDate, $currentDate) {
$query->where('start_date', '<=', $startDate)
->where('end_date', '>=', $endDate)
->where('end_date', '>', $currentDate);
})
->orWhere(function ($query) use($startDate, $endDate, $currentDate) {
$query->where('start_date', '>=', $startDate)
->where('end_date', '<=', $endDate)
->where('end_date', '>', $currentDate);
})
->orWhere(function ($query) use($startDate, $endDate, $currentDate) {
$query->where('start_date', '<=', $startDate)
->where('end_date', '>=', $startDate)
->where('end_date', '>', $currentDate);
})
->orWhere(function ($query) use($startDate, $endDate, $currentDate) {
$query->where('start_date', '<=', $endDate)
->where('end_date', '>=', $endDate)
->where('end_date', '>', $currentDate);
I have a problem with my Larvel Query it doesn't work as desired.
It should Filter "Campaigns" with the attributes Teams, Channels, Region and Timeperiod with Start and Enddate. The Timeperiod is no problem.
The user can Filter for differen Teams/Channels/Region and can choose no, one or more Attribute, which should connect as or.
The desired Result should give all Campaign which has the selected Teams AND Channels AND Region. But at the moment I get every Campaign which has the selected Teams OR the selected Channels OR the selected Region.
public function searchCampaigns($page, $limit, $data)
{
$startDate = $data['startDate'];
$endDate = $data['endDate'];
$campaigns = Campaign::distinct()->select('campaigns.*')
->join('campaign_team', 'campaign_team.campaign_id', '=', 'campaigns.id')
->join('campaign_region', 'campaign_region.campaign_id', '=', 'campaigns.id')
->join('campaign_channel', 'campaign_channel.campaign_id', '=', 'campaigns.id')
->join('teams', 'campaign_team.team_id', '=', 'teams.id')
->join('regions', 'campaign_region.region_id', '=', 'regions.id')
->join('channels', 'campaign_channel.channel_id', '=', 'channels.id')
//Interesting Part
->whereIn('teams.id', $data['teams'])
->whereIn('regions.id', $data['regions'])
->whereIn('channels.id', $data['channels'])
->where(function ($query) use ($startDate, $endDate) {
$query->where('campaigns.start_date', '>=', $startDate)
->where('campaigns.end_date', '<=', $endDate);
})
->orWhere(function ($query) use ($startDate, $endDate) {
$query->where('campaigns.end_date', '<=', $endDate)
->where('campaigns.end_date', '>=', $startDate);
})
->orWhere(function ($query) use ($startDate, $endDate) {
$query->where('campaigns.start_date', '>=', $startDate)
->where('campaigns.start_date', '<=', $endDate);
})
->orWhere(function ($query) use ($startDate, $endDate) {
$query->where('campaigns.start_date', '<=', $startDate)
->Where('campaigns.end_date', '>=', $endDate);
}) ->orderBy('start_date', 'asc');
$result['count'] = sizeof($campaigns->lists('id'));
$result['campaigns'] = $campaigns->skip($limit * ($page - 1))->take($limit)->get();
return $result;
}
Try this one. It shall work. Let me know if any issues happen :)
public function searchCampaigns($page, $limit, $data)
{
$result = [];
// Checking Validity of Start Date
if (empty($data['startDate']) || (Carbon::createFromFormat('Y-m-d', $data['startDate']) === false))
return $result;
// Checking Validity of End Date
if (empty($data['endDate']) || (Carbon::createFromFormat('Y-m-d', $data['endDate']) === false))
return $result;
// Comparing Start & End Date
$startDate = Carbon::parse($data['startDate']);
$endDate = Carbon::parse($data['endDate']);
if($startDate->gt($endDate))
return $result;
if($endDate->lt($startDate))
return $result;
$startDate = $data['startDate'];
$endDate = $data['endDate'];
$campaigns = Campaign::distinct()->select('campaigns.*')
->join('campaign_team', 'campaign_team.campaign_id', '=', 'campaigns.id')
->join('campaign_region', 'campaign_region.campaign_id', '=', 'campaigns.id')
->join('campaign_channel', 'campaign_channel.campaign_id', '=', 'campaigns.id')
->join('teams', 'campaign_team.team_id', '=', 'teams.id')
->join('regions', 'campaign_region.region_id', '=', 'regions.id')
->join('channels', 'campaign_channel.channel_id', '=', 'channels.id')
->whereIn('teams.id', $data['teams'])
->whereIn('regions.id', $data['regions'])
->whereIn('channels.id', $data['channels'])
->where('campaigns.start_date', '>=', $startDate)
->where('campaigns.end_date', '<=', $endDate);
->orderBy('start_date', 'asc');
$result['count'] = sizeof($campaigns->lists('id'));
$result['campaigns'] = $campaigns->skip($limit * ($page - 1))->take($limit)->get();
return $result;
}