I have a complex query which group bys multiple columns, this is an example
$queryBuilder
->join('e.something', 's')
->where('...')
->addGroupBy('e.id s.someField');
Using ->getQuery()->getResults() returns me an array of entities like I'd expect.
[
0 => App\Entity\ExampleEntity,
1 => App\Entity\ExampleEntity
]
If I try to count the results returned using a select like so:
$queryBuilder
->select('COUNT(e.id)')
->join('e.something', 's')
->where('...')
->addGroupBy('e.id s.someField');
I am returned an array of arrays, inside each array is the count. This isn't what I want. Removing the group by I'm given the correct result however the group by is required.
[
[
1 => '11',
],
[
1 => '4',
]
]
I'm stuck on how I can count the results of the group by. I have tried using distinct and I also do not want to count in PHP.
Related
I'm new to firebase. I made a game similar to flappy bird, and now I would like to add a leader board.
Could someone help me organize the game score data in firestore so that I can run queries to retrieve:
Top 12 high scores achieved in the last 7 days
Or
Lowest high score recorded in the last 24hrs?
Since these queries contain filters on different fields (score & date) I'm not sure how to do this in firestore.
My initial attempt was to create a collection containing documents, and each document holds playerName, score, date. But it seems I can't query the data if it is formatted this way.
For example If I have 3 documents containing this data:
{ playerName: 'A', score: 500, date: 1649079891803 },
{ playerName: 'B', score: 400, date: 1649079891802 },
{ playerName: 'C', score: 567, date: 1649079891801 },
and I run this query:
query( collection.ref,
orderBy( 'date', 'desc' ),
where( 'date', '>=', last24hrs ),
orderBy( 'score' ),
limit( 1 ),
);
firebase is returning to me playerName A, score 500 rather than Player B score 400 which is the lowest one.
If I make player C's date be the largest in the group of 3, then firebase will return it ...
I'm looking for a query that will return the lowest score in the last day
In fact, after returning a result of data from the database using Doctrine,
I'm trying to add the row count number, without calling another query request.
This is my function:
public function search(QueryBuilder $qb, string $search)
{
$qb = $qb->addSelect('COUNT(n) as count');
$search = $this->escape($search);
$qb->andWhere(
$qb->expr()->like('n.title', $qb->expr()->literal('%'.$search.'%'))
);
$qb->setMaxResults(2);
}
This is my DQL:
SELECT n, COUNT(n) as count FROM CoreBundle\Entity\News n LEFT JOIN n.category c WHERE n.title LIKE '%re%'
And I need to return as a result a all my data with a count key that refer to the number of rows.
The problem that I'm getting only the first row with id = 1, and it seems that the count number is correct.
So the result should by something like that:
['count' => 2 , [Newsn1,Newsn2]
Don't tell me to use array_count because I need to get the count of rows in the database, and I have a setMaxResults function, so I will not get a real number of rows.
I don't know the configuration of your table, I just can imagine. So, here's my try:
For getting counts for all titles in your table:
# SQL
SELECT COUNT(id) AS count, GROUP_CONCAT(title SEPARATOR ', ') AS titles FROM newses GROUP BY title
# DQL. assuming you are using a Repository method:
$qb = $this->createQueryBuilder('n');
$qb
->select("COUNT(n.id) AS count, GROUP_CONCAT(n.title SEPARATOR ', ') AS titles")
->leftJoin('n.category', 'c')
->groupBy('n.title')
;
return $qb->getQuery()->getArrayResult();
For getting counts for a particular title:
# SQL
SELECT COUNT(id) AS count, GROUP_CONCAT(title SEPARATOR ', ') AS titles FROM newses WHERE n.title LIKE '%news%' GROUP BY title
# NewsRepository.php
public function getTitlesCount($title)
{
$qb = $this->createQueryBuilder('n');
$qb
->select("COUNT(n.id) AS count, GROUP_CONCAT(n.title SEPARATOR ', ') AS titles")
->leftJoin('n.category', 'c')
->where('n.title LIKE :title')
->setParameter('title', "%{$title}%")
->groupBy('n.title')
;
return $qb->getQuery()->getArrayResult();
}
I'm trying to execute an inner query and set parameters without success, i always get:
Invalid parameter number: number of bound variables does not match number of tokens
This is my query :
SELECT i2
FROM MyBundle:Identity i2
INNER JOIN MyBundle:Property\\Mapped\\Email propertyEmail WITH propertyEmail.identity = i2
INNER JOIN MyBundle:Channel channel WITH propertyEmail.channel = channel
WHERE (
SELECT COUNT(mappedEmail)
FROM MyBundle:Property\\Mapped\\Email mappedEmail
WHERE mappedEmail.identity = i2
AND mappedEmail.channel = :channel
AND mappedEmail.createdAt <= :dateFrom
) > 0
AND IDENTITY(propertyEmail.channel) <> :channel
AND propertyEmail.createdAt <= :dateFrom
GROUP BY i2
And this is how i put as subquery:
$innerQuery = $queryBuilder->getEntityManager()->createQuery($query)
->setParameters([
'channel' => $channelId,
'dateFrom' => $dateFrom
])
;
$queryBuilder->andWhere($queryBuilder->expr()->notIn($alias, $innerQuery->getDQL()));
That return the error :
Invalid parameter number: number of bound variables does not match number of tokens
If I execute the query as single query all works right.
Thanks for suggestion.
Try to apply the parameters to the main query as follow:
$innerQuery = $queryBuilder->getEntityManager()->createQuery($query);
$queryBuilder
->andWhere($queryBuilder->expr()->notIn($alias, $innerQuery->getDQL()))
->setParameters([
'channel' => $channelId,
'dateFrom' => $dateFrom
]);
Table1(identity1, a1,b1)
Table2(identity, foreign(identity1),foreign(identity1))
Now when I use this query
$query = $qb->select('a1', ' b1')
->from('table2', 'm1')
->join('ApiMapBundle:tabl1, 'u1', 'WITH', $qb->expr()->orX('m1. foreign(a1) =u1.identity', 'm1. foreign(b1) = u1.identity '))
->andWhere('m1.identity=:tt')
->setParameter('tt', $cn)
->getQuery()
->getResult();
Now the problem with this query is that sometimes it gives id let's tt:5 so it gives me a value like this
Array(
0 => Array(id => 1, b1=> 8000225),
1 => Array(id => 9, b1 => 8000234)) given).
Basically in table the values structure is like this
Table2(Identity=5,foreign1=9,foreign2=1)
Any idea that how can I exactly get the given structure? Because in some cases it is fine they give me proper foreign 1 and foreign 2 but in other cases it make it alternative. Any idea?
I'm hoping someone can help with a problem I can't wrap my limited knowledge around. I have two SQL queries like:
SELECT
SUM(Matrix.[ITEM1]) AS [ITEM1],
SUM(Matrix.[ITEM2]) AS [ITEM2]
FROM StoreList
INNER JOIN Matrix ON StoreList.[Store Number] = Matrix.[Store Number]
WHERE (StoreList.Region = '#Value')
SELECT
ITEMTYPES.type_description,
ITEMS.Quantity
FROM ITEMS
INNER JOIN ITEMTYPES ON ITEMS.type_id = ITEMTYPES.id
Now, what these do is return a list of values that I want to multiply together (for example, to get a final quantity for [ITEM1], multiply [ITEM1] by [Items.Quantity]. However the ITEMTYPES table holds a list of descriptions of ITEM (and primary key id), which is used for entering new items. The STORELIST table uses the descriptors in ITEMTYPES as column names(ie. The ItemTypes table has records called [Item1], [Item2]; the Column names in Matrix are also [Item1], [Item2]).
The question is this - from my limited experience (and I do mean limited - < 6months with SQL) there is no way to perform a calculation based upon column names - I would have to abstract out the totals in some way to another table, with additional fields for Region (this explains the sum() statements in query 1) and perform calculations that way - or does some have a more elegant idea?
Table Structures as per Laurence's request:
For Table [MATRIX]:
[Store Number] (PK, int, not null)
[ITEM1] (int, default 0)
[ITEM2] (int, default 0)
For Table [ITEMTYPES]:
[id] (PK, int, not null),
[ITEMTYPE] (nvarchar(50), not null)
Now, Example data (excuse any formatting issues!):
[MATRIX]
Store Number ITEM1 ITEM2
------------------------------
123456 1 15
678920 31 9
[ITEMTYPE]
id ITEMTYPE
------------------------------
1 ITEM1
2 ITEM2
Appreciate the response!
Ok so you have 2 results returned from these 2 queries into 2 different ordered pair lists or arrays... so you have the first result in the format of
//FROM THE MATRIX QUERY
array(
[0] => array(
"Store Number" => 123456,
"ITEM1" => 1,
"ITEM2" => 15
),
[1] => array(
"Store Number" => 678920,
"ITEM1" => 31,
"ITEM2" => 9
),
ETC...
)
//FROM YOUR ITEM QUERY
array(
[0] => array(
"type_description" => "ITEM1",
"quantity" => ???
),
[1] => array(
"type_description" => "ITEM2",
"quantity" => ???
)
ETC......
)
ok now you can do 2 foreach loops where you iterate through the 2 arrays
foreach(arrayMatrix as store){
foreach(arrayItems as item){
print "Store: "+ store['Store Number']+" ITEM: " + item['type_description']+" total: "+ (store[item['type_description']] * item['quantity']);
}
}
now I wrote this in psuedo code and Im not sure if you can translate this well into VB. With those 2 foreach or while loops or whatever you can databind the results to the grid or put them in another array or list... I hope this helps at all.