Doctrine query returns extra field in result - mysql

I have a Doctrine query;
$q = Doctrine_Query::create()->select('s.monthly_volume')
->from('SearchVolume s')
->innerJoin('s.Keywords k')
->where('k.group_id = ?',array($group_id));
I just want it to return the monthly_volume value in the result array. It currently returns monthly_volume and id, I don't want it to return the id in result.

Doctrine automatically adds the primary key field to the results in almost every type of hydration mode.
In a case like this where you want a simple array and only have a single field being selected, the answer is the Single Scalar Hydration mode. Use it like this:
$q = Doctrine_Query::create()->select('s.monthly_volume')
->from('SearchVolume s')
->innerJoin('s.Keywords k')
->where('k.group_id = ?');
$monthly_volumes = $q->execute(array($group_id), Doctrine_Core::HYDRATE_SINGLE_SCALAR);
You should find that $monthly_volumes is a simple one-dimensional array containing only the value(s) you wanted.

Related

Query Builder appending a limit by itself

I have a "big" query with 10 joins, and finally a single where condition.
I also have about 6 arrays, each being filled with a select statement from said query.
$first_array = $query->select()->first();
In two of the arrays, I get the data using get() instead of first(). The issue is, the get() method is only returning one row, when I know for a fact that there are two that match the condition. I used the toSql() method to see the resulting query, only to find there is a limit 1 being appended to the query that I did not place. Is the limit being appended because I'm using first() in some of the queries, which is limiting my results to one row? I've tried executing the query in my database manager and after removing the limit 1 from the query it does return the two rows I'm expecting.
The issue was, if you did this like I did:
$array1 = $query->select()->first();
$array2 = $query->select()->first();
$array3 = $query->select()->first();
$array4 = $query->select()->first();
$array5 = $query->select()->get();
The first() method calls set the limit 1, and using get() afterwards does not remove the limit.
If you use get() first then first() like so:
$array5 = $query->select()->get();
$array1 = $query->select()->first();
$array2 = $query->select()->first();
$array3 = $query->select()->first();
$array4 = $query->select()->first();
then the issue does not occur.
Replace first() with get() is the answer. first() is for retrieving a single model: https://laravel.com/docs/8.x/eloquent#retrieving-single-models where get() returns you the collection of results: https://laravel.com/docs/8.x/eloquent#collections

Symfony Doctrine: Search in simple_array

I got values stored in my database column field as value1,value2,value3,value4, so a simple_array column.
So i'm using Doctrine to make a search using this:
$searchQuery = $this->getDoctrine()
->getRepository('AppBundle:Ads')
->createQueryBuilder('p')
->andWhere("p.vals <= :value2")
->setParameter('value2', $request->query->get('value2'));
->orderBy("p.creationtime", 'DESC');
So expecting value2 is in the 2nd position of a simple array like value1,value2,value3, how can i ask QueryBuilder to select the second value in the string?
I think this query try to get all the values in p.vals, results are not right, shound select just one.
How can I select eg. the 2nd value in p.vals?
I believe you cannot access nth item of an array column using pure Mysql since the data is serialized, in order to do it I'd create a simple function
public function getItemFromArray(array $array, $index)
{
return isset($array[$index]) ? $array[$index] : null;
}
And if you want to find item with condition use
array_filter()

PDO prepared statements increment/decrement by bool

In my POST file, I need to change the order of my items. I basically send a parameter called moveDown which is a bool, to check whether the item is higher or lower. So, I got this to get my parameter:
$moveDown = filter_input(INPUT_POST, 'moveDown', FILTER_VALIDATE_BOOLEAN);
I got another parameter for the item id. This is just a simple filter_input, nothing special.
$itemId = filter_input(INPUT_POST, 'itemId', FILTER_SANITIZE_NUMBER_INT);
Now, I need to use that variable to define whether to increment or decrement the order column. So I tried this:
$changeOrderStmt = $cmsDbh->prepare('UPDATE `items` SET `order` = ? WHERE `id` = ?');
$changeOrderStmt->execute(array('`order` ' . ($moveDown ? '+' : '-') . ' 1', $itemId));
However, now the order column is 0. I really don't want to concatenate the query string and rather use PDO params. Is this possible or not?

filling a select field with model with certain tag - laravel

I have no problem with selecting a model tagged with certain tag
$lis = Capacitytype::find(124)->entities()->orderBy('name','asc')->get();
In my Capacitytype model I have this relation:
public function entities()
{
return $this->belongsToMany('App\Models\Entity', 'entity_capacitytypes', 'capacitytype_id', 'entity_id');
}
MY PROBLEM:
I wish to use the same selection f models to fill a select field in a form. (I use select2.js)
When I try to implement this code
$lis = array(null => 'Commitee') + Capacitytype::find(124)->entities()->orderBy('name','asc')->lists('name', 'id')->all();
I get this error:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in field list is ambiguous (SQL: select name, id from entities inner join entity_capacitytypes on entities.id = entity_capacitytypes.entity_id where entities.deleted_at is null and entity_capacitytypes.capacitytype_id = 6 order by name asc)
I tried to solve this issue by adding table name to my code, but this is as far as I was able to go:
->lists('entities.name', 'entities.id')
My Question:
how modify the code to get the desired collection for my select field?
Thank you.
You could make use of Laravel's with() to perform an eager loading as a workaround for this issue. To do so, just pass the name of the relation (i.e. entities) to the method:
Capacitytype::find(124)->with('entities')->orderBy('name','asc')->lists('entities.name', 'entities.id');
Or else, you could first fetch the records, and then reformat it to match your usecase:
$list = Capacitytype::find(124)->entities()->orderBy('name','asc')->get()->toArray();
As such, you can refine the returned list of arrays, to match your id => name format (hence, a substitute for the lists method).
$refinedList = array();
foreach($list as $entity){
$refinedList[$entity['id']] = $entity['name'];
}
And, there you go.

Why is count(id) resulting 3 dimensional array?

Im using this direct query method in cakephp to get a count (against the norms of MVC).
$count = $this->History->query("SELECT count(id) AS x FROM ratings WHERE id='3' AND employee='28'");
But it turns out that, i need to use $count[0][0]['x'] to get the value.
Why isnt it available at $count['x']?
in your case it will return it in a general way: 0 = iterate over all models, and again 0 since you dont have a specific model name). your result will always be in $count[0][0]['fieldname'] then.
it is highly recommended to always use the wrapper methods if possible.
why are you not using the cakephp database wrapper methods as documented?
$count = $this->History->find('count', array('conditions'=>array('id'=>3, 'employee'=>28));
?
it would result in the expected output x
Simply, its because the function
$this->History->query(....);
does not return a single dimensional array. I will suggest you to create a helper function, which extracts the single dimensional array and return it.
function single_query($query) {
$result = $this->History->query($query);
return $result[0][0];
}
then use it
$count = $this->single_query("SELECT count(id) AS x FROM ratings WHERE id='3' AND employee='28'");