doctrine 2 - query builder conditional queries... If statements? - doctrine

My query is doctirne 2. i have a status field in users, private or
public. i want to be able to run this query and display all comments
where status= public and private only if userid = current logged in
user id(which i know, $loggerUserVarID)
$q = $this->em->createQueryBuilder()
->select('c')
->from('\Entities\Comments', 'c')
->leftJoin('c.users', 'u')
->where('status = public') ??? display all public comments but private if it belpongs to the logged in user.?
->setParameter(1, $loggerUserVarID)
->getQuery();
at the moment, i am using an if statement after i get thee results, is there a way to do an if statement inside this query?

So, you want to return Comments "If status is 'public' or the ownerId is $loggedUserVarID", right?
Note that if $loggedUserVarID matches the owner, you don't really care about status.
Check out the querybuilder and dql docs. They explain pretty clearly how to put together complex where conditions.
What you probably want is something like:
$q = $this->em->createQueryBuilder()
->select('c')
->from('\Entities\Comments', 'c')
->join('c.users', 'u')
->where(
$qb->expr()->orX(
$qb->expr()->eq('status','public'),
$qb->expr()->eq('u.id',$loggedInUser)
)
)
->setParameter(1, $loggerUserVarID)
->getQuery();

Related

Yii2 subquery GROUP BY in active record

can I convert this query
"SELECT * FROM (SELECT * FROM blog_post ORDER BY data DESC) blog_post GROUP BY blog_id LIMIT 2"
into a Yii2 active record query?
Thx
Ms
Yes, you can do this.
Yii2 gave us a wonderful library support.
You can form custom sql query and pass this query in findBySql() like:
$sql = "Some query/nested query";
$result = ModelClass::findBySql($sql);
Visit Yii official documentation.
BlogPost::find()
->orderBy('data DESC')
->groupBy('blog_id')
->limit(2)
->all();
I suppose you can do in this way :
Ⅰ:create a subQuery where you select from.
$blogPostQuery = BlogPostModel::find()->orderBy(['data' => SORT_DESC]);
Ⅱ:Get activeRecord results. The from params is an exist Query.
$models = (new yii\db\Query)
->from(['blog_post ' => $blogPostQuery])
->groupBy(['blog_id'])
->limit(2)
->all();
ps:
see yii\db\query->from()-detail in Yii Api;
(public $this from ( $tables )) $tables can be either a string (e.g. 'user') or an array (e.g. ['user', 'profile']) specifying one or several table names··· or a sub-query or DB expression
Have a try!I hope it`s useful for you:))

Can I run a CodeIgniter database query without clearing it from the class?

I am using the CodeIgniter database class to generate results and then use the pagination class to navigation through them. I have a model that retrieves member results from the table. I would like to calculate the total number of rows from the query so I can pass this to the pagination class. The count_all db helper function won't suffice because that doesn't take in account any "where" or "join" clauses that I include.
If this is my query:
$this->db->select('m.user_id AS id, m.email_address, m.display_name, m.status, UNIX_TIMESTAMP(m.join_date) AS join_date,
l.listing_id, COUNT(l.member_id) AS total_listings,
g.group_id AS group_id, g.title AS group_title')
->from('users AS m')
->join('listings AS l', 'm.user_id = l.member_id', 'left')
->join('groups AS g', 'm.group_id = g.group_id', 'left')
->group_by('m.user_id');
How can I continue to use this query if I wanted to do something like this:
if($query_total = $this->db->get()){
$this->total_results = $query_total->num_rows();
}
$this->db->limit($limit, $offset);
if($query_members = $this->db->get()){
return $query_members->result_array();
}
Update: In other words, I want to run a query with the get() method without clearing it from the query builder when it's done running so I can use the top part of the query later.
You can get it by using Active Record Caching (the last category on that page).
$this->db->start_cache(); // start caching
$this->db->select('m.user_id AS id, m.email_address, m.display_name, m.status, UNIX_TIMESTAMP(m.join_date) AS join_date,
l.listing_id, COUNT(l.member_id) AS total_listings,
g.group_id AS group_id, g.title AS group_title')
->from('users AS m')
->join('listings AS l', 'm.user_id = l.member_id', 'left')
->join('groups AS g', 'm.group_id = g.group_id', 'left')
->group_by('m.user_id');
$this->db->stop_cache(); // stop caching
Then you can use that query as much as you want.
if($query_total = $this->db->get()){
$this->total_results = $query_total->num_rows();
}
$this->db->limit($limit, $offset);
if($query_members = $this->db->get()){
return $query_members->result_array();
}
You can also flush the cache when you don't want that cached query anymore.
$this->db->flush_cache();
Hope it will be useful for you.
You are not passing any table name in $this->db->get() function.
Thank you

Symfony2 subquery within Doctrine entity manager

I need to perform this query:
SELECT * FROM (SELECT * FROM product WHERE car = 'large' ORDER BY onSale DESC) AS product_ordered GROUP BY type
In Symfony2 using the entity manager.
My basic query builder would be :
$query = $em->getRepository('AutomotiveBundle:Car')
->createQueryBuilder('p')
->where('pr.car = ?1')
->andWhere('pr.status = 1')
->orderBy('pr.onSale', 'DESC')
->setParameter(1, $product->getName())
->groupBy('p.type')
->getQuery();
But I cannot work out how to add in a subquery to this.
Ive tried making a separate query and joining it like:
->andWhere($query->expr()->in('pr.car = ?1',$query2->getQuery()));
But I get:
Call to undefined method Doctrine\ORM\Query::expr()
One trick is to build two queries and then use getDQL() to feed the first query into the second query.
For example, this query returns a distinct list of game ids:
$qbGameId = $em->createQueryBuilder();
$qbGameId->addSelect('distinct gameGameId.id');
$qbGameId->from('ZaysoCoreBundle:Event','gameGameId');
$qbGameId->leftJoin('gameGameId.teams','gameTeamGameId');
if ($date1) $qbGameId->andWhere($qbGameId->expr()->gte('gameGameId.date',$date1));
if ($date2) $qbGameId->andWhere($qbGameId->expr()->lte('gameGameId.date',$date2));
Now use the dql to get additional information about the games themselves:
$qbGames = $em->createQueryBuilder();
$qbGames->addSelect('game');
$qbGames->addSelect('gameTeam');
$qbGames->addSelect('team');
$qbGames->addSelect('field');
$qbGames->addSelect('gamePerson');
$qbGames->addSelect('person');
$qbGames->from('ZaysoCoreBundle:Event','game');
$qbGames->leftJoin('game.teams', 'gameTeam');
$qbGames->leftJoin('game.persons', 'gamePerson');
$qbGames->leftJoin('game.field', 'field');
$qbGames->leftJoin('gameTeam.team', 'team');
$qbGames->leftJoin('gamePerson.person', 'person');
// Here is where we feed in the dql
$qbGames->andWhere($qbGames->expr()->in('game.id',$qbGameId->getDQL()));
Kind of a long example but i didn't want to edit out stuff and maybe break it.
You can use DBAL for performing any sql query.
$conn = $this->get('database_connection');//create a connection with your DB
$sql="SELECT * FROM (SELECT * FROM product WHERE car =? ORDER BY onSale DESC) AS product_ordered GROUP BY type"; //Your sql Query
$stmt = $conn->prepare($sql); // Prepare your sql
$stmt->bindValue(1, 'large'); // bind your values ,if you have to bind another value, you need to write $stmt->bindValue(2, 'anothervalue'); but your order is important so on..
$stmt->execute(); //execute your sql
$result=$stmt->fetchAll(); // fetch your result
happy coding

How to order by count in Doctrine 2?

I'm trying to group my entity by a field (year) and do a count of it.
Code:
public function countYear()
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('b.year, COUNT(b.id)')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->addOrderBy('sclr1', 'DESC')
->addGroupBy('b.year');
$query = $qb->getQuery();
die($query->getSQL());
$result = $query->execute();
//die(print_r($result));
return $result;
}
I can't seem to say COUNT(b.id) AS count as it gives an error, and
I do not know what to use as the addOrderby(???, 'DESC') value?
There are many bugs and workarounds required to achieve order by expressions as of v2.3.0 or below:
The order by clause does not support expressions, but you can add a field with the expression to the select and order by it. So it's worth repeating that Tjorriemorrie's own solution actually works:
$qb->select('b.year, COUNT(b.id) AS mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
Doctrine chokes on equality (e.g. =, LIKE, IS NULL) in the select expression. For those cases the only solution I have found is to use a subselect or self-join:
$qb->select('b, (SELECT count(t.id) FROM \My\Entity\Album AS t '.
'WHERE t.id=b.id AND b.title LIKE :search) AS isTitleMatch')
->from('\My\Entity\Album', 'b')
->where('b.title LIKE :search')
->andWhere('b.description LIKE :search')
->orderBy('isTitleMatch', 'DESC');
To suppress the additional field from the result, you can declare it AS HIDDEN. This way you can use it in the order by without having it in the result.
$qb->select('b.year, COUNT(b.id) AS HIDDEN mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
what is the error you get when using COUNT(b.id) AS count? it might be because count is a reserved word. try COUNT(b.id) AS idCount, or similar.
alternatively, try $qb->addOrderby('COUNT(b.id)', 'DESC');.
what is your database system (mysql, postgresql, ...)?
If you want your Repository method to return an Entity you cannot use ->select(), but you can use ->addSelect() with a hidden select.
$qb = $this->createQueryBuilder('q')
->addSelect('COUNT(q.id) AS HIDDEN counter')
->orderBy('counter');
$result = $qb->getQuery()->getResult();
$result will be an entity class object.
Please try this code for ci 2 + doctrine 2
$where = " ";
$order_by = " ";
$row = $this->doctrine->em->createQuery("select a from company_group\models\Post a "
.$where." ".$order_by."")
->setMaxResults($data['limit'])
->setFirstResult($data['offset'])
->getResult();`

Doctrine query only returning one row?

I'm new to Doctrine but somewhat familiar with SQL. I have a very simple schema with Users and Challenges. Each Challenge has a "challenger id" and a "opponent id" which are foreign keys into the User table. I want to print a list of all challenges, with the output being the names from the User table. Here is my Doctrine query;
$q = Doctrine_Query::create()
->select('u1.name challenger, u2.name opponent')
->from('Challenge c')
->leftJoin('c.Challenger u1')
->leftJoin('c.Opponent u2');
The problem is that this only returns one row. I've used the getSqlQuery() command to look at the generated SQL which ends up being:
SELECT u.name AS u__0, u2.name AS u2__1 FROM challenge c
LEFT JOIN user u ON c.challenger_id = u.id
LEFT JOIN user u2 ON c.opponent_id = u2.id
When run in a 3rd party SQL client this query retrieves all of the rows as expected. Any idea how I can get all of the rows from Doctrine? I'm using $q->execute() which I understand should work for multiple rows.
Thanks.
For me it worked by chaning the hydration mode:
$result = $query->execute(array(), Doctrine_Core::HYDRATE_SCALAR);
Set result set then returns an array instead of objects.
I just ran into this issue and in my case the problem was that my query didn't select any field from the FROM table. Example:
$query = Doctrine_Query::create()
->select(
'ghl.id as id,
ghl.patbase_id as patbase_id,
ghl.publication_no as publication_no,
ghl.priority_no as priority_no
'
)
->from('GridHitListContents ghlc')
->leftJoin('ghlc.GridHitList ghl')
As you can see there is no selected field from the GridHitListContents table.
with a $query->count() I got 2000ish results, but with $query->fetchArray() only the first one.
When I added
$query = Doctrine_Query::create()
->select(
'ghlc.id,
ghl.id as id,
...
'
)
->from('GridHitListContents ghlc')
->leftJoin('ghlc.GridHitList ghl')
I got back all my results.
$query->fetchOne() work fine for me.
Use this $result = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY)

Resources