what the meaning mergeBindings in laravel - php

hy I'm new in laravel 4 and I have found code like this
$sub = Abc::where(..)->groupBy(..); // Eloquent Builder instance
$count = DB::table( DB::raw("({$sub->toSql()}) as sub") )
->mergeBindings($sub->getQuery())
->count();
my quetion is
1. what the meaning mergeBindings($sub->getQuery()) and give me example for using mergeBindings

assume your first query is like this:
$sub = Abc::where('type', 1)->groupBy(..);
then when we convert it to sql:
$sub->toSql();
this will return query string some thing like this:
SELECT * FROM abc where abc.type = ? GROUp BY ...
you can see the "?" as the type value which will be binded (replaced by 1) when the PDO executes that query string
So when we use that sub query in another query as you do in
$count = DB::table( DB::raw("({$sub->toSql()}) as sub") )
->mergeBindings($sub->getQuery())
->count();
you have converted the first sub query to sql string, BUT the second query does not know any thing about your first sub query binding which in this example the value 1
so we need to merge the binding from the first sub query into the last query
so that the last query when executes it will know the value 1 and binds it to the
where clause in replace of "?", and your final executed query will be something like this
(SELECT count(*) from abc where type = 1 GROUP BY ...) as sub
and thats it the use of mergeBindings() method
i hope this makes things clear for your question.
thanks,

Related

Yii2 query give different result with sql query

"Table1":
id
name
1
Ulrich
2
Stern
"Table2":
id
school
tid
1
A
1
2
B
1
I want to join 2 table to get all information. With SQL query like this:
SELECT Table1.id,
name,
school
FROM `Table1`
INNER JOIN `Table2`
ON Table1.id = Table2.tid
It gives me all information as I expect (I mean 2 rows with name 'Ulrich').
But when I do with Yii2 query:
$query = self::find();
$query -> alias('t1')
-> innerJoin(['t2'=>'Table2'], 't1.id=t2.tid')
$result = NULL;
if($total = $query->count()) {
$result = $query
-> select([t1.*, t2.school])
->asArray()
->all()
;
$result[0]['count'] = $total;
}
it only gives me 1 row with name 'Ulirch'.
Can anyone help me with this problem. Thank you very much.
If you use ActiveRecord::find() method to create query you will get instance of yii\db\ActiveQuery. This is query designed to load ActiveRecord models. Because of that if you do any type of join and your result set contains primary key of your main model (The model which find() method was called to create query) the ActiveQuery will remove any rows it considers duplicate.
The duplicates are recognised based on main model primary key so the rows in resultset will be considered duplicate even if the data from joined table are different. That's exactly what happened in your case.
To avoid that you have to use query builder instead of ActiveQuery.
Your query can look for example like this:
$query = (new \yii\db\Query())
->from(['t1' => self::tableName()])
->innerJoin(['t2'=>'Table2'], 't1.id=t2.tid');

CodeIgniter - Binding a EXIST subquery

First of all I'm new to the framework. Check the query I'm trying to transcript using the CI database object.
$where = "(".$this->tbl.".invoiceNumber = '".substr($searchFor,3)."'
OR EXISTS (SELECT 1 FROM op_orders_products WHERE idProduct = ".(is_numeric(substr($searchFor,3)) ? substr($searchFor,3) : '-1')."
AND idOrder = ".$this->tbl.".id)
)";
Should I do a separate subquery? Would like to make it all in one.
This is how I started. I wanna make sure the variables are binded and not passed as strings as in the original query.
$this->db->group_start()
->where($this->tbl.".invoiceNumber", substr($searchFor, 3))
->or_group_start()
// I'm missing this EXISTS select subquery
->group_end()
->group_end()
Thanks a lot for the help.
There is no EXISTS equivalent in Codeigniter's Query Builder Class that I'm aware of. So I'd just write it like this:
$this->db->group_start()
->where($where)
->group_end()
see documentation here
binding:
with CodeIgniter you can bind variables to your query like this:
$sql = "SELECT * FROM table WHERE a= ? AND b= ?";
$query = $this->db->query($sql, array($a,$b));
This binds variables $a and $b to the corresponding positions (?) inside the query string.
escaping
$this->db->escape()
this function escapes string data and adds single quotes around it.

Symfony 2 Multiple Selects with counts on the same table?

Ok I have a flag field on one table, open or closed which is boolean. I am trying to build one query that would take that field and count them based on that flag. Then I will need to group them by account ID
Here is what I am working with now,
$GetTest1 = $GetRepo->createQueryBuilder('s') <- I had 'w' in here but all that did was add an index and not a second alias?
->select(' (count(s.open_close)) AS ClosedCount, (count(w.open_close)) AS OpenCount ')
->where('s.open_close = ?1')
//->andWhere('w.open_close = ?2')
->groupBy('s.AccountID')
->setParameter('1', true)
//->setParameter('2', false)
->getQuery();
Is what I want do-able? I know (or at lest think) that I can build a query with multiple table alias? - Please correct me if I am wrong.
All help most welcome.
Thanks
This DQL query will group the rows in table by accountId and for each of them it will give you count for yes (and you can get count for no by substracting that from total).
BTW I found writing straight DQL queries much more straightforward than writing QueryBuilder queries (which i use only when i need to dynamically construct the query)
$results = $this->get("doctrine")->getManager()
->createQuery("
SELECT t.accountId, SUM(t.openClose) as count_yes, COUNT(t.accountId) as total
FROM AppBundle:Table t
GROUP BY t.accountId
")
->getResult();
foreach ($results as $result) {
//echo print_r($result);
//you can get count_no as $result["total"] - $result["count_yes"];
}

Access the results from a previously executed query

I have a nested relationship and I would like to filter them, using the result that comes from the first query run by Eloquent.
My Eloquent query is:
$entry = Entry::with([
'products.unit',
'products.area'
])->find($id);
The query log shows me that Eloquent runs this query first:
select * from entry where entry.deleted_at is null and entry.id = ? limit 1
And I would like to use its result in this second query, also run by Eloquent:
select area.*,
area_product.product_id, area_product.quota as pivot_quota,
area_product.month as pivot_month
from area inner join area_product
on area.id = area_product.area_id
where area.deleted_at is null and area_product.product_id in (?)
I would like to put a constraint inside it using the month value that comes from the first query.
Is there a way to do it using Eloquent?
I was thinking in something like this:
$entry = Entry::with([
'products.unit',
'products.area' => function ($q) {
// using month here!
}
])->find($id);

Update query and not replace existing result, just combine old result + new result with comma

I would like to do a Update query but not replace existing result, combine both result with comma become array. My query will be something like this:
$query = "UPDATE outlet_type_location SET treatment_id = **',$id'** WHERE outlet_type_id = '$outlet_type_id'";
Thanks for everyone giving me advice.
use FIND_IN_SET like this
SELECT * FROM outlet_type_location WHERE FIND_IN_SET('$treatment_id',treatment_id) > 0

Categories