How to implement a join in a join with Eloquent - eloquent

I have a question how to combine two joins in Laravel's eloquent. One join also belongs to the other.
The concept is you have timeslots and I want to know how many attendees there for that timeslot.
The challenge is: I want all available timeslots and a booking is only valid when it's done live, not canceled and completed.
With the query below the booking and counting part is fine, but I only get the timeslots with bookings done.
$this->selectRaw('timeslots.id, timeslots.time_from , timeslots.time_till, duration_minutes,
count(attendees.id) as bookedSlots,
capacity as total,
capacity - count(attendees.id) as leftTickets')
->where('timeslots.project_id', $projectId)
->where('invoices.type', '!=', 'IncompleteOrder')
->whereDate('time_from', '=', $date)
->leftJoin('attendees', function($query) {
$query->on('timeslots.id', '=', 'attendees.timeslot_id')
->where('attendees.is_live', '=', 1)
->where('attendees.is_cancelled', '=', 0);
})
->leftJoin('invoices', 'attendees.invoice_id', '=', 'invoices.id')
->groupBy('timeslots.id')
->get();

This was a/the solution:
$response = $this->selectRaw('timeslots.id, timeslots.time_from , timeslots.time_till, duration_minutes,
count(attendees.id) as bookedSlots,
capacity as total,
capacity - count(attendees.id) as leftTickets')
->where('timeslots.project_id', $projectId)
->whereDate('time_from', '=', $date)
->leftJoin('attendees', function($query) {
$query->on('timeslots.id', '=', 'attendees.timeslot_id')
->where('attendees.is_live', '=', 1)
->where('attendees.is_cancelled', '=', 0);
})
->leftJoin('invoices', function($query) {
$query->on('invoices.id', '=', 'attendees.invoice_id')
->where('invoices.type', '!=', 'IncompleteOrder');
})
->groupBy('timeslots.id')
->get();

Related

how to show only last record with query builder in laravel

I only want to display the latest data from the tanggal_ins that I have marked, how to?
This is my json data:
And this is my query:
$cuti = DB::table('t_cuti as cuti')
->join('m_karyawan as kary', 'kary.nik', '=', 'cuti.nik')
->join('m_rumah_sakit as rs', 'rs.kd_rs', '=', 'kary.kd_rs')
->join('m_unit as unit', 'unit.kd_unit', '=', 'kary.kd_unit')
->join('m_jabatan as jab', 'jab.kd_jabatan', '=', 'kary.kd_jabatan')
->leftJoin('t_cuti_adjust as adj', function ($leftJoin) {
$leftJoin->on('adj.nik', '=', 'cuti.nik')
->latest();
})
->select('adj.tanggal_ins','cuti.saldo_cuti','kary.nik','kary.nm_karyawan','rs.nm_rs','unit.nm_unit','jab.nm_jabatan')
->whereYear('adj.tanggal_ins', '<', $year)
->orWhere('adj.tanggal_ins', null)
->get();
Thanks.
Use orderBy.
->orderBy('id', 'desc')->first();
This will make descending order by ID.
->orderBy('id', 'desc')
and use first() instead of get().

Eloquent Left Join with more than one condition

I need to mount a left join with more than one condition, but I have not found the correct settings
LEFT JOIN palpite ON partida.partida_id = palpite.partida_fk AND palpite.usuario_fk = 20
eloquent code
$results = DB::table('partida')
->join('time as mandante', 'mandante.time_id', '=', 'partida.mandante_fk')
->join('time as visitante', 'visitante.time_id', '=', 'partida.visitante_fk')
->leftJoin('palpite', function ($join) {
$join->on('partida.partida_id', '=', 'palpite.partida_fk')
->on('partida.usuario_fk', '=', '20');
})
->select([
'partida.partida_id',
'partida.rodada',
'partida_data',
'partida.local',
'partida.mandante_fk',
'partida.visitante_fk',
'mandante.abreviacao AS mandante_abreviacao',
'mandante.nome AS mandante_nome',
'mandante.escudo60x60 AS mandante_escudo',
'visitante.abreviacao AS visitante_abreviacao',
'visitante.nome AS visitante_nome',
'visitante.escudo60x60 AS visitante_escudo',
'palpite.placar_mandante',
'palpite.placar_visitante'
])
->where('mandante.aposta', 1)
->orWhere('visitante.aposta', 1)
->orderBy('partida.partida_data', 'ASC')
->get();
Try this:
$results = DB::table('partida')
->join('time as mandante', 'mandante.time_id', '=', 'partida.mandante_fk')
->join('time as visitante', 'visitante.time_id', '=', 'partida.visitante_fk')
->leftJoin('palpite', function ($join) {
$join->on('partida.partida_id', '=', 'palpite.partida_fk');
$join->on('partida.usuario_fk', '=', '20');
})
->select([
'partida.partida_id',
'partida.rodada',
'partida_data',
'partida.local',
'partida.mandante_fk',
'partida.visitante_fk',
'mandante.abreviacao AS mandante_abreviacao',
'mandante.nome AS mandante_nome',
'mandante.escudo60x60 AS mandante_escudo',
'visitante.abreviacao AS visitante_abreviacao',
'visitante.nome AS visitante_nome',
'visitante.escudo60x60 AS visitante_escudo',
'palpite.placar_mandante',
'palpite.placar_visitante'
])
->where('mandante.aposta', 1)
->orWhere('visitante.aposta', 1)
->orderBy('partida.partida_data', 'ASC')
->get();

Fix Mongo query in Lumen

I have a query in the lumen. But it does not work. The query is :
return Order::whereBetween('source_longitude', [$minLon_try_one, $maxLon_try_one])
->whereBetween('source_latitude',[51.365807806703,51.454384193297])
->where('status','=','pending')
->where('created_at','<=', 2016-04-07 12:00:35)
->where('created_at','>=', 2016-04-07 11:55:35)
->orWhere(function($query)
{
$query->whereBetween('source_longitude', [51.321519613407, 51.498672386593])
->whereBetween('source_latitude',[35.612195271526,35.756086728473])
->where('status','=','pending')
->where('created_at','<=',2016-04-07 11:55:35)
->where('created_at','>=',2016-04-07 11:50:35);
}
)->get();
But when I remove orWhere function from the query I get expected result
You probably using orWhere a little bit wrong. You need to put where to another where to execute query properly. What You are doing now is something like that where a is 1 and b is 2 or (c is 3 and d is 4), but I believe, You want to do something like that where (a is 1 and b is 2) or (c is 3 and d is 4)
Try this one:
return Order::where(function ($query) {
$query->whereBetween('source_longitude', [$minLon_try_one, $maxLon_try_one])
->whereBetween('source_latitude', [51.365807806703, 51.454384193297])
->where('status', '=', 'pending')
->where('created_at', '<=', '2016-04-07 12:00:35')
->where('created_at', '>=', '2016-04-07 11:55:35');
})->orWhere(function ($query) {
$query->whereBetween('source_longitude', [51.321519613407, 51.498672386593])
->whereBetween('source_latitude', [35.612195271526, 35.756086728473])
->where('status', '=', 'pending')
->where('created_at', '<=', '2016-04-07 11:55:35')
->where('created_at', '>=', '2016-04-07 11:50:35');
})->get();

Select query in zend framework 2.2 with multiple where clause and order by desc

Select query in zend framework 2.2 with multiple where clause and order by desc.
My query is
Select 'vch_no' from vaucher_mst where 'series_sno'=12 and vchtype_sno=13 order by vch_no,desc
How can I perform this query? Here is my try:
public function getvchno() {
$select = new select();
$select->from($this->table);
$this->select('vch_no');
$where = new where();
$where->equalTo('series_sno',12);
$where->equalTo('vchtype_sno',13);
$select->where($where);
$order_by='vch_no';
$order=Select::ORDER_DESCENDING;
$select->order($order_by . ' ' . $order);
$limit=1;
$select->LIMIT(1);
$statement = $this->select($select);
print_r($statement);die;
if (!$row) {
throw new \Exception("Could not find row $id");
}
}
I do not know Zend 2 but according to the doc, this should work:
// Select 'vch_no' from vaucher_mst where 'series_sno'=12 and vchtype_sno=13 order by vch_no,desc
$select = new Select();
$select->from('vaucher_mst')
->columns(array('vch_no'))
->where(array('series_sno = 12', 'vchtype_sno = 13'))
->order('vch_no DESC');
Keep me informed :)

left join with subqueries in laravel

How can i do to reproduce this sql statement below with query builder or eloquent? I've tried using DB::raw... and join('something', function ($join)... but it is not working. If anyone knows how to figure this out, please show me an example.
SELECT
musica.titulo,
p.qtd_pedidos,
a.qtd_avaliacoes,
a.media_avaliacoes
FROM
musica
LEFT JOIN (
SELECT musica_id, COUNT(pedido.id) as qtd_pedidos
FROM pedido GROUP BY pedido.musica_id
) as p ON p.musica_id = musica.id
LEFT JOIN (
SELECT musica_id, COUNT(avaliacao.id) as qtd_avaliacoes,
ROUND(AVG(avaliacao.nota),1) as media_avaliacoes
FROM avaliacao GROUP BY avaliacao.musica_id
) as a ON a.musica_id = musica.id
Assuming you have described Musica, Pedido and Avaliacao models with their relations:
Musica::with(
array('pedido' => function($query) {
$query->select(DB::raw('musica_id, COUNT(pedido.id) as qtd_pedidos'))
->groupBy('musica_id');
},
'avaliacao' => function($query) {
$query->select(DB::raw(
'musica_id, '
. 'COUNT(avaliacao.id) as qtd_avaliacoes, '
. 'ROUND(AVG(avaliacao.nota),1) as media_avaliacoes'
))
->groupBy('musica_id');
}
)
)->get();