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();
Related
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();
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().
How can I dynamically add extra conditions to 'WHERE' clauses in TYPO3 database queries please? The new TYPO3 Version 8 docs say how to make fixed queries, but not variable ones.
In the past, I could create a SQL statement and modify it dynamically like this:
if (condition) {
$strWhere = 'some SQL';
} else {
$strWhere = 'same SQL with extra bits';
}
$dbRes = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
"*", // SELECT ...
"tableName", // FROM ...
$strWhere , // WHERE...
etc.
I can't see how to do something like this using Querybuilder. What I want to achieve is an expression that does something like this
if (condition) {
->where($queryBuilder->expr()->eq(... ))
}
else {
->where($queryBuilder->expr()->eq(... ))
->andWhere($queryBuilder->expr()->eq(... ))
}
Any hints would be much appreciated. Thanks.
Solved. My mistake was in thinking that the various parts of a Query builder statement HAVE to come together - they don't.
So this:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tablename');
$queryBuilder
->select('uid', 'header', 'bodytext')
->from('tt_content')
->where(
$queryBuilder->expr()->eq('bodytext', $queryBuilder->createNamedParameter('klaus')),
$queryBuilder->expr()->eq('header', $queryBuilder->createNamedParameter('a name'))
)
->execute();
can also be split into parts, such as:
switch ($scope) {
case 'limitfields':
$queryBuilder->select('uid','header','bodytext');
break;
default:
$queryBuilder->select('*');
break;
}
$queryBuilder
->from('tt_content')
->where(
$queryBuilder->expr()->eq('bodytext', $queryBuilder->createNamedParameter('klaus')),
$queryBuilder->expr()->eq('header', $queryBuilder->createNamedParameter('a name'))
)
->execute();
$queryBuilder = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\ConnectionPool')->getQueryBuilderForTable('tx_igldapssoauth_config');
$expressionBuilder = $queryBuilder->expr();
$conditions = $expressionBuilder->andX();
$conditions->add(
$expressionBuilder->eq('somefield', 1)
);
$conditions->add(
$expressionBuilder->eq('someotherfield', 2)
);
$rows = $queryBuilder->select('*')
->from('tx_igldapssoauth_config')
->where(
$queryBuilder->expr()->eq('uid', 1)
)
->andWhere($conditions)
->execute()->fetchAll();
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();
This method is published as offical example
->where("price < $minimumPrice OR price > $maximumPrice")
is such method safe?
want to write it as
->where("price < ? OR price > ?", $minimumPrice, $maximumPrice)
are there any poissibility?
and I can't split it into 2 where statements because plan to write query
->where("1 OR 2")
->where("3 OR 4")
Try this:
$query->where('(price < ?', $minPrice)
->orWhere('price > ?)', $maxPrice)
->where('some = ?', $some_other_variable);
will result:
where ((price < $minPrice) OR (price > $maxPrice)) AND (some = $some_other_variable)
Note the double (( )) in OR part
If I have complex WHERE clauses I use the db adapters' ->quoteInto() method like:
$where = '('
. $dbAdapter->quoteInto('price1 < ?', $price1)
. ' OR '
. $dbAdapter->quoteInto('price1 > ?', $price1)
. ')'
. ' AND '
. '('
. $dbAdapter->quoteInto('price2 < ?', $price2)
. ' OR '
. $dbAdapter->quoteInto('price2 > ?', $price2)
. ')'
;
$select->where($where);
Some times you will want to make SQL queries which have parenthesis around multiple where conditions that would be easily parsed with foreach, but you do not want to be bothered about string manipulation. For example, you would have a list of users with id's and that have to be of certain type, you can try this:
$select = $this->select();
$subWhere = $this->select();
foreach(array_keys($idArr) as $key => $value) {
$subWhere->orWhere('id=?', $value);
}
$select->where(implode(' ', $subWhere->getPart('WHERE')))->where('type=?', 'customer');
This will result in "SELECT * FROM table WHERE ((id=X) OR (id=Y) OR (id=Z)...) AND (type='customer');"
The idea developed a bit further, you could extend the Zend_Db_Table_Abstract:
public function subWhere($col, $binds, $operands, $andOr = 'OR' )
{
$subWhere = $this->select();
if(strtolower($andOr) == 'or') {
foreach($binds as $key => $value) {
$subWhere->orWhere($col.$operands[$key].'?', $value);
}
return implode(' ', $subWhere->getPart('WHERE'));
}
elseif (strtolower($andOr) == 'and') {
foreach ($binds as $key => $value) {
$subWhere->where($col.$operands[$key].'?', $value);
}
return implode(' ', $subWhere->getPart('WHERE'));
}
else {
return false;
}
}
And use it as:
$this->select()->where($this->subWhere($col, $binds, $operands));
Of course you should allow mixed $cols, $operands = array() defaulting as '=?' etc. but for the sake of simplicity I left that out. But I believe we should use native SQL functions like IN(), BETWEEN ... AND ..., NOT BETWEEN ... AND ...? Zend Framework doesn't make your life very easy though.
$select->where($db->quoteInto('field1 < ? OR', $minPrice)
. $db->quoteInto('field1 > ?', $maxPrice))
->where($db->quoteInto('field2 < ? OR', $value2)
. $db->quoteInto('field2 > ?', $value3));