how to search using the sum of case when in cakephp - php

I want to do implement a search in the generated data of the sum count of a case when in cakephp with or or conditions in each data.
SELECT `Branches`.`name` AS `Branches__name` , `Branches`.`code` AS `Branches__code` , (
COUNT(
CASE WHEN `prodCarried`.`carried` =1
THEN 1
END )
) AS `carried` , (
COUNT(
CASE WHEN `prodCarried`.`carried` =0
THEN 1
END )
) AS `unCarried`
FROM `branches` `Branches`
INNER JOIN `products_carried_per_branches` `prodCarried` ON ( prodCarried.company_id = Branches.company_id
AND prodCarried.branch_code = Branches.code )
WHERE (
`Branches`.`company_id` =200017
AND `Branches`.`deleted` =0
AND `prodCarried`.`deleted` =0
)
GROUP BY `code`
HAVING COUNT(
CASE WHEN `prodCarried`.`carried` =1
THEN 1
END ) =39
the picture shows the mysql result without the having code
while this is my cakephp code, I want to implement the having sql into cakephp or condition to search the generated sum count or search the data name and code. is this possible or nah
$carriedCase = $query->newExpr()
->addCase(
$query->newExpr()->add(['prodCarried.carried' => '1']),
1,
'integer'
);
$unCarriedCase = $query->newExpr()
->addCase(
$query->newExpr()->add(['prodCarried.carried' => '0']),
1,
'integer'
);
//disctinct code
$query ->select([
'name',
'code',
'carried' => $query->func()->count($carriedCase),
'unCarried' => $query->func()->count($unCarriedCase),
'prodCarried.id',
'prodCarried.validity_start',
'prodCarried.validity_end',
]);
$query ->distinct([
'code'
]);
$query->join([
'prodCarried' => [
'table' =>'products_carried_per_branches',
'type' => 'inner',
'conditions' => [
'prodCarried.company_id = Branches.company_id',
'prodCarried.branch_code = Branches.code',
]
]
]);
$query->where(function (QueryExpression $exp, Query $q) use($option,$search){
$exp->eq('Branches.company_id', $option['company_id']);
$exp->eq('Branches.deleted', 0);
$exp->eq('prodCarried.deleted', 0);
if(!empty($search)){
$orConditions = $exp->or_(function (QueryExpression $or) use ($search) {
$or->like('name', "%$search%");
$or->like('code', "%$search%");
//****************************
return $or;
});
$exp->add($orConditions);
}
return $exp;
});

Depending on your DBMS you can refer to the aggregate of the select list:
$query->having([
'carried' => $searchCount,
]);
Otherwise you have to recreate the aggregate:
$query->having(
function (
\Cake\Database\Expression\QueryExpression $exp,
\Cake\ORM\Query $query
) use (
$carriedCase,
$searchCount
) {
return $exp->eq(
$query->func()->count($carriedCase),
$searchCount
);
}
);
See also
Cookbook > Database Access & ORM > Query Builder > Aggregates - Group and Having

Related

Is it Possible to do a datatable search using the generated sumcount of the sum case in CAKEPHP [duplicate]

I want to do implement a search in the generated data of the sum count of a case when in cakephp with or or conditions in each data.
SELECT `Branches`.`name` AS `Branches__name` , `Branches`.`code` AS `Branches__code` , (
COUNT(
CASE WHEN `prodCarried`.`carried` =1
THEN 1
END )
) AS `carried` , (
COUNT(
CASE WHEN `prodCarried`.`carried` =0
THEN 1
END )
) AS `unCarried`
FROM `branches` `Branches`
INNER JOIN `products_carried_per_branches` `prodCarried` ON ( prodCarried.company_id = Branches.company_id
AND prodCarried.branch_code = Branches.code )
WHERE (
`Branches`.`company_id` =200017
AND `Branches`.`deleted` =0
AND `prodCarried`.`deleted` =0
)
GROUP BY `code`
HAVING COUNT(
CASE WHEN `prodCarried`.`carried` =1
THEN 1
END ) =39
the picture shows the mysql result without the having code
while this is my cakephp code, I want to implement the having sql into cakephp or condition to search the generated sum count or search the data name and code. is this possible or nah
$carriedCase = $query->newExpr()
->addCase(
$query->newExpr()->add(['prodCarried.carried' => '1']),
1,
'integer'
);
$unCarriedCase = $query->newExpr()
->addCase(
$query->newExpr()->add(['prodCarried.carried' => '0']),
1,
'integer'
);
//disctinct code
$query ->select([
'name',
'code',
'carried' => $query->func()->count($carriedCase),
'unCarried' => $query->func()->count($unCarriedCase),
'prodCarried.id',
'prodCarried.validity_start',
'prodCarried.validity_end',
]);
$query ->distinct([
'code'
]);
$query->join([
'prodCarried' => [
'table' =>'products_carried_per_branches',
'type' => 'inner',
'conditions' => [
'prodCarried.company_id = Branches.company_id',
'prodCarried.branch_code = Branches.code',
]
]
]);
$query->where(function (QueryExpression $exp, Query $q) use($option,$search){
$exp->eq('Branches.company_id', $option['company_id']);
$exp->eq('Branches.deleted', 0);
$exp->eq('prodCarried.deleted', 0);
if(!empty($search)){
$orConditions = $exp->or_(function (QueryExpression $or) use ($search) {
$or->like('name', "%$search%");
$or->like('code', "%$search%");
//****************************
return $or;
});
$exp->add($orConditions);
}
return $exp;
});
Depending on your DBMS you can refer to the aggregate of the select list:
$query->having([
'carried' => $searchCount,
]);
Otherwise you have to recreate the aggregate:
$query->having(
function (
\Cake\Database\Expression\QueryExpression $exp,
\Cake\ORM\Query $query
) use (
$carriedCase,
$searchCount
) {
return $exp->eq(
$query->func()->count($carriedCase),
$searchCount
);
}
);
See also
Cookbook > Database Access & ORM > Query Builder > Aggregates - Group and Having

Laravel Query Builder Where OR whereIn array

I am having some trouble in Laravel using the query builder to select users based on two where clauses.
The first where clause would contain multiple where statements to select a user based on some conditions. If this fails in the OR part I would like to check simply if the user ID is in the array.
Would be grateful for some advice on how I could achieve this.
Thanks.
$rs = DB::table('tblUser')
->select('name')
->where(function($q) {
$q->where(function($q){
$q->where('fid', '=', $this->argument('fid'))
->where('type', '<', 10)
})
->orWhereIn('id', $userIdSArray);
})
->get();
$userIdSArray = [ '2', '4', '5' ];
$rs = DB::table( 'Users' )
->select( 'name' )
->where( function ( $q ) use ( $userIdSArray ) {
$q->where( function ( $q ) {
$q->where( 'fid', '=', $this->argument( 'fid' ) )
->where( 'type', '<', 10 );
})
->orWhereIn( 'id', $userIdSArray );
})
->get();
I think you need to pass $userIdSArray in Query builder . And You also forgot (;) after [->where( 'type', '<', 10 )]

How to write subquery IN conditional zend 2

I have MySQL Query i want to write this query zend 2.
select billsec, call_status, Count(*)
from (
select
billsec,
if(ANSWERED_NUM is Null, 'Missed', 'Answered') call_status
from cust_info
where billsec in (
select id
from `users`
where `account_id` = 452 and `added_by` = 20694 and `status` = 'active'
)
)a
group by a.billsec,a.call_status
in zend 2 am trying to write like this but
$adapter = $this->getAdapter();
$resultset = $this->select( function( Select $select ) use ( $request, $adapter ) {
$sub1 = new Select( 'users' );
$sub1->columns( array( 'id' ) );
$sub1->where( array( 'account_id' => '452','added_by' => '20694','status' => 'active' ) );
$sub2 = new Select( 'cust_info' );
$sub2->columns(array("id","billsec", "if(ANSWERED_NUM is Null, 'Missed','Answered')"=>"call_status"));
$sub2->where('billsec IN(?)', new \Zend\Db\Sql\Expression( '?', array( $sub1 ) ));
var_dump( $sub2->getSqlString( $adapter->getPlatform() ) );die();
});
When am print this query output like this:
"SELECT `cust_info`.`id` AS `id`, `cust_info`.`billsec` AS `billsec`, `cust_info`.`call_status` AS `if(ANSWERED_NUM is Null, 'Missed','Answered')` FROM `cust_info` WHERE billsec IN('')"
Here am not able to write IN condition Query, thank in advance.

Symfony doctrine group by max date timestamp

I would like to select values from table o by some conditions and grouped by groupKey. This query is working fine, but now query return first grouped value for my. I need to retrieve grouped values with MAX timestamp.
An example if there are two or more values with groupKey I need that one where o.createdAt value is newer.
$qb = $this->createQueryBuilder('order');
$expr = $qb->expr();
return $qb
->select('order, (CASE WHEN order.tsmOrderNumber IS NOT NULL THEN order.tsmOrderNumber ELSE order.id END) as groupKey')
->where('order.user =:user')
->andWhere('order.status =:status')
->andWhere(
$expr->orX(
$expr->andX(
$expr->isNotNull('order.wayBillNumber'),
$expr->neq('order.wayBillNumber', "''"),
$expr->between('order.createdAt', ':dateFrom', ':dateTo')
),
$expr->andX(
$expr->orX(
$expr->isNull('o.tsmNumber'),
$expr->eq('o.tsmNumber', '\'\'')
),
$expr->between('order.createdAt', ':dateFrom2', ':dateTo')
)
)
)
->setParameters(
[
'status' => Order::STATUS_COMPLETED,
'user' => $user,
'dateFrom' => (new \DateTime())->modify('-2 month'),
'dateFrom2' => (new \DateTime())->modify('-6 month'),
'dateTo' => new \DateTime()
]
)
->groupBy('groupKey')
->orderBy('order.createdAt', 'DESC')
->getQuery()
->getResult();

Laravel Query Builder "select" strange behaviour

I have a problem with the following code:
public function index() {
$qObj = \DB::table('customers as c')
->join('companies_has_customers as chc', 'chc.comhc_cus_id', '=', 'c.cus_id')
->join('cuscategory as cc', 'chc.comhc_cca_id', '=', 'cc.cca_id')
->join('transactions as t','t.trn_cus_id', '=','c.cus_id')
->select('t.trn_id');
$qObj->where('comhc_com_id', '=', $this->companyId);
$res = array(
'count' => $qObj->count(),
'items' => $qObj->get()
);
//print_r($this->showLastQuery());
return parent::prepareResponse($res, 200, 'customers');
}
And this piece of code produces following SQL query:
select * from `customers` as `c`
inner join `companies_has_customers` as `chc` on `chc`.`comhc_cus_id` = `c`.`cus_id`
inner join `cuscategory` as `cc` on `chc`.`comhc_cca_id` = `cc`.`cca_id`
inner join `transactions` as `t` on `t`.`trn_cus_id` = `c`.`cus_id`
where comhc_com_id` = 1
QUESTION:
Why QueryBuilder produce select *... instead of select t.trn_id... as is requested in above syntax?
Change the order:
$res = array(
'items' => $qObj->get(),
'count' => $qObj->count()
);
and it will work.
But better, instead of querying DB twice, do this:
$items = $qObj->get();
$res = array(
'items' => $items,
'count' => count($items)
);
The problem with your code is count() method behaviour - it resets the columns property (set with select), that's all.
Put it in $qObj->get(['t.trn_id']) like this:
$res = array(
'items' => $items = $qObj->get(['t.trn_id']),
'count' => count($items) // count the cached $items
);
Instead of select ( Remove select('t.trn_id')).

Categories