How to select everything in column with Doctrine and Symfony - php

I'm trying to build small query with QueryBuilder where category parameter that can be passed to query or not.
$category = 'Boots';
If not I'd like to select all categories.
I use "where" for this. In mySql you can use "WHERE column = column" and everything is selected. I tried this with the builder but it doesn't work:
$qb = $this->createQueryBuilder('p')
->select("p.id, p.price, stock.qty, p.images, category.name,
p.model, s.size AS size, c.name AS color,
b.name AS brand, category.name AS catName")
->innerJoin('p.stocks', 'stock')
->innerJoin('p.brand', 'b')
->innerJoin('stock.size','s')
->innerJoin('stock.color', 'c')
->innerJoin('p.category', 'category')
->where('category.name = :category')
->andWhere('s.size IN (:sizes)')
->andWhere('b.name IN (:brands)')
->andWhere('p.price > :priceFrom')
->andWhere('p.price < :priceTo')
->setParameter('category', 'category.name') /// ??? the problem is here
->setParameter('sizes', $sizes, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)
->setParameter('brands', $brands, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)
->setParameter('priceFrom', $priceFrom)
->setParameter('priceTo', $priceTo)
->groupBy('p.model')
->getQuery()
->getResult();
Check the lines:
->where('category.name = :category')
->setParameter('category', 'category.name') /// ??? the problem is here
When i try to set column to column it doesn't work. I tried also diferrent combinations like, but no results. Any advice? Thanks

Related

Join same table to get other value in symfony 6

someone know how to join same table in symfony 6 doctrine to get different results?
I tried something like that
public function findAllStats(){
return $this->createQueryBuilder('a')
->select('count(a.id) as count, a.countryCode, count(acc) as all_accounts, count(ao) as all_online_today')
->leftJoin('a.accounts', 'acc', 'with', "acc.owner = a.id")
->andWhere('a.countryCode is not null')
->groupBy('a.countryCode')
->orderBy('count(a.id)', 'ASC')
->having('count(a.id) > 2')
->setParameter('today' , (new \DateTime())->setTime(0,0,0))
->getQuery()
->getScalarResult();
}
i just want to get next results and its okay:
country_code,
count of all users,
count of all accounts (relation)
but i dont know how to add:
count of all users updated today
i tried this:
public function findAllStats(){
return $this->createQueryBuilder('a')
->select('count(a.id) as count, a.countryCode, count(acc) as all_accounts, count(ao) as all_online_today')
->leftJoin('a.accounts', 'acc', 'with', "acc.owner = a.id")
->andWhere('a.countryCode is not null')
->groupBy('a.countryCode')
->orderBy('count(a.id)', 'ASC')
->having('count(a.id) > 2')
->setParameter('today' , (new \DateTime())->setTime(0,0,0))
->getQuery()
->getScalarResult();
}
but it doesn't works. Some solutions to join same table with different Where criteria?
but it doesn't works. Some solutions to join same table with different Where criteria?
Okay i found the solution. I used Class of entity and left join but is that a correct way?
->leftJoin(User::Class, 'ao', 'with', "ao.id = a.id AND ao.updatedAt >= :today")

Order by count of relational field

I have the following relations:
Member one-to-many Product
Product many-to-one Member
This is the query that I have that works:
$qb = $this->createQueryBuilder('m');
$qb
->where('m.Authority = :Authority')
->setParameter('Authority', Authority::CREATOR)
->innerJoin('m.Product', 'p')
->select('COUNT(p) AS HIDDEN item_count', 'm')
->groupBy('m')
->orderBy("item_count", "ASC");
However when I add additional parameters for product status
$qb = $this->createQueryBuilder('m');
$qb
->where('m.Authority = :Authority')
->setParameter('Authority', Authority::CREATOR)
->andWhere('p.Status = :Status')
->setParameter('Status', 1);
->innerJoin('m.Product', 'p')
->select('COUNT(p) AS HIDDEN item_count', 'm', 'p')
->groupBy('p')
->orderBy("item_count", "ASC");
The order by doesn't happen anymore. I dumped the value for item_count and it's alway 1. Has anyone encountered the same problem? The goal here is to get a list of Members with Products with status = 1 ordered by the number of Products.
Edit:
If I change groupBy('p') to groupBy('m'), it will only load one related Product for each Member
For anyone who struggled with the same problem, this is how I did it:
$qb = $this->createQueryBuilder('m');
$qb
->where('m.Authority = :Authority')
->setParameter('Authority', Authority::CREATOR)
->andWhere('p.Status = :Status')
->setParameter('Status', 1);
->select('p, m')
->addSelect('(SELECT COUNT(DISTINCT p1)
FROM Eccube\Entity\Member m1
INNER JOIN Eccube\Entity\Product p1
WHERE m1.Authority = ' . Authority::CREATOR . ' AND p1.Status = 1 AND p1.Creator = m.id
) AS hidden item_count')
->innerJoin('m.Product', 'p')
->groupBy('p')
->orderBy("item_count", "ASC");
It works but I don't understand why this is p1.Creator = m.id ? If I use m1.id it will just sum up the item count.
Edit: Added updated code after Jakumi's comment regarding the join. Even though both code works, the second one makes more sense.
$qb = $this->createQueryBuilder('m');
$qb
->where('m.Authority = :Authority')
->setParameter('Authority', Authority::CREATOR)
->andWhere('p.Status = :Status')
->setParameter('Status', 1);
->select('p, m')
->addSelect('(SELECT COUNT(DISTINCT p1)
FROM Eccube\Entity\Member m1
INNER JOIN m1.Product p1
WHERE m1.Authority = ' . Authority::CREATOR . ' AND p1.Status = 1 AND p1.Creator = m
) AS hidden item_count')
->innerJoin('m.Product', 'p')
->groupBy('p')
->orderBy("item_count", "ASC");

Symfony 4 query elements from joined table if they exist

I have two tables gifts and gift_tags how can I select all gifts with tags that are not present in $avoidTags array only if gift has tags. The way my query works now it selects only the gifts that have at least one tag in gift_tags table and it is not in $avoidTags array, but I need also those that have no tags at all.
$response = $qb
->select('g, tags')
->leftJoin('g.tags', 'tags')
->andwhere($qb->expr()->notin("tags.name", ":avoidTags"))
->setParameters(new ArrayCollection([
new Parameter('avoidTags', $avoidTags),
]))
->getQuery()
->getResult();
With the mysql, it can do with this query
SELECT
gift.*, tag.*
FROM
gift
LEFT JOIN tag ON gift.id = tag.gift_id
WHERE gift.id NOT IN (
SELECT g.id FROM gift AS g LEFT JOIN tag AS t ON g.id = t.gift_id WHERE t.name IN ('test', 'test2')
)
So with the doctrine QB it maybe something like this
$subQb = $this->_em->createQueryBuilder()
->select('gift.id')
->leftJoin('gift.tags', 'tags')
->where($qb->expr()->orX(
$qb->expr()->in("tags.name", ":avoidTags")),
))
->getQuery();
$response = $qb
->select('g, tags')
->leftJoin('g.tags', 't')
->where($qb->expr()->notin("g.id", $subQb->getDql())))
->setParameters(new ArrayCollection([
new Parameter('avoidTags', $avoidTags),
]))
->getQuery()
->getResult();

multiple addOrderBy in doctrine/symfony2

I wanted to order the item pictures that I have in my database based on the shop priority that has the highest priority first, then number of likes, and the created date:
So I have the following:
$picturesQuery = $qb->select('DISTINCT p')
->from("AppMainBundle:Picture", 'p')
->innerJoin('p.shop', 'shop')
->addOrderBy('shop.priority', 'DESC')
->addOrderBy('p.numberoflikes', 'DESC')
->addOrderBy('p.created', 'DESC')
;
However it doesn't work. I have a shop which has the highest priority, but the item from that shop isn't showing on the top of the query results. Is it okay to have multiple order by? How can I achieve what I want?
You need to fetch join shop Something like this (untested).
$picturesQuery = $qb->select('DISTINCT p', 'shop')
Reference

MySQL Join two different columns in the same table twice in CodeIgniter

I have announcements table, where I store announcements.catid (category id).
Categories table categories are used to be nested with the use of categories.pid.
What I am trying to do, is to get the categories nested one by one inside the multidimensional array.
Here is the image of how I want it to be inside highlighted part:
and here is the code:
public function get_mixed( $limit = NULL, $offset = NULL )
{
$this->db
->select('
announcements.id,
announcements.catid,
announcements.uid,
categories.title AS section,
categories.title AS category,
announcements.title,
announcements.text,
announcements.views,
announcements.created,
announcements.modified,
announcements.pubdate
')
->join('categories', 'announcements.catid = categories.id', 'left')
->join('categories as section', 'categories.pid = section.id', 'left')
->order_by('created DESC, '.$this->_order_by);
return $this->db->get( $this->_table_name, $limit, $offset )->result();
}
I tried first with by creating a section alias, but it gets me the same results.
Maybe there is a better approach ?
If you are aliasing one of the categories joins as section, then you would need to reference any fields you want from that categories table as section.[field] (for example, section.title)
Not knowing exactly what you want, my best guess at your revised query would be:
$this->db
->select('
announcements.id,
announcements.catid,
announcements.uid,
section.title AS section,
categories.title AS category,
announcements.title,
announcements.text,
announcements.views,
announcements.created,
announcements.modified,
announcements.pubdate
')
->join('categories', 'announcements.catid = categories.id', 'left')
->join('categories as section', 'categories.pid = section.id', 'left')
->order_by('created DESC, '.$this->_order_by);

Categories