Doctrine Query Builder Select Count with Case - php

I have the following sql-statement that I want to transform into doctrine query builder. The goal is to count how many ratings exist with rating value 1 and with rating value 2.
SELECT
COUNT(CASE WHEN rating.rating = 1 THEN rating.rating END) as rat1,
COUNT(CASE WHEN rating.rating = 2 THEN rating.rating END) as rat2
FROM rating
This sql statement is working fine - but when I try to transform it into a Doctrine statement, it does not anymore. When nothing should get counted (because no ratings for this value exist), it returns me a "1" instead of a 0. How can I tell doctrine to simply return a zero when there is nothing to count?
I tried it by removing the "ELSE 0" , but then I get an error that this part is required..
return $qb
->addSelect('COUNT(CASE WHEN r.rating = 1 THEN r.rating ELSE 0 END) as rat_1')
->addSelect('COUNT(CASE WHEN r.rating = 2 THEN r.rating ELSE 0 END) as rat_2')
->getQuery()
->getResult();
Regards,
"sum" is not required - example:
votings 2,2,2,2,2 should return 5 , because the rating with value 2 got voted 5 times.

To count distinct id's in one column depending on the value in another column the answer from Fuzzy Tree does not work in this case.
To count only the distinct values you should give null as a parameter and set it to null like:
->addSelect('COUNT(DISTINCT(CASE WHEN r.rating = 1 THEN rating.rating ELSE :nada END)) as rat_1')
->setParameter(':nada', null)

As vkp mentioned, you can use SUM but instead of summing the rating, sum either a 1 or a 0 to simulate a COUNT
SUM(CASE WHEN r.rating = 1 THEN 1 ELSE 0 END)

Related

function results dont match query results php

EDIT: the responses work well but not quite what i was after i dont think i explained it very well, i just want to return 1 result per function so count how many odd numbers are in the result and count how many even numbers are in the result?
sql fiddle for the data
http://sqlfiddle.com/#!9/dfbfa7/1
Im trying to count even and odd numbers by splitting the the results using 2 functions but my results dont match up to the results in the mysql table.
data
select number from table group by number
results
1,4,6,7,8,9,11,12
function to return odd number count
SELECT
COUNT(CASE WHEN (number% 2) > 0 THEN number ELSE NULL END) as odd
FROM test.table
WHERE date = CURDATE() and time > now() - interval 60 second group by number
LIMIT 1
and the function to return even number count
SELECT
COUNT(CASE WHEN (number% 2) = 0 THEN number ELSE NULL END) as even
FROM test.table
WHERE date = CURDATE() and time > now() - interval 60 second group by number
LIMIT 1
i was hoping the results would be
odd = 4
even = 4
but instead im getting
odd = 8
even = 0
where am i going wrong?
Maybe try something like thise.
For even numbers:
COUNT(SELECT * FROM `table` WHERE mod(number, 2)=0);
For odd numbers:
COUNT(SELECT * FROM `table` WHERE mod(number, 2)>0);
This will return the only number of odd and even numbers, then collect those numbers with php.
COUNT will add up all the lines it traverses
In your case you must use SUM:
SUM(CASE WHEN (number% 2) > 0 THEN 1 ELSE 0 END) as odd
SUM(CASE WHEN (number% 2) = 0 THEN 1 ELSE 0 END) as even
for simple operations the IF is much cleaner than the CASE:
SUM(IF(number % 2 > 0, 1, 0)) as odd
SUM(IF(number% 2 = 0, 1, 0)) as even
The reason your query is returning wrong result is probably because you are using limit 1 try removing it also if you have to use group by use group by number in before you do calculations for this query, i have altered the query here for example.
SELECT
count(CASE WHEN (a.number% 2) = 0 THEN a.number ELSE NULL END) as even,
count(CASE WHEN (a.number% 2) <> 0 THEN a.number ELSE NULL END) as odd
FROM (select number from test group by number) a;
http://sqlfiddle.com/#!9/dfbfa7/22
for the set up you have created im getting 5 even and 5 odd in results, may be you have to recheck the condition you have in where clause if your results are different with actual data.

how can i select data and sub query group by

When i select data only show first lot data . but i need all lot data.
Here is my query:
SELECT lot,
(select count(pass) FROM pass_fail_result where pass=0) toatl_fail,
(select count(pass) FROM pass_fail_result where pass=1) toatl_pass FROM pass_fail_result group by lot;
I want to show all pass result like pass=10 and fail=2
The easiest way to do this is via conditional aggregation, where we count or sum CASE expressions which target the failing or passing records:
SELECT
lot,
COUNT(CASE WHEN pass = 0 THEN 1 END) AS toatl_fail,
COUNT(CASE WHEN pass = 1 THEN 1 END) AS toatl_pass
FROM pass_fail_result
GROUP BY
lot;

How I can count with GROUP BY and condition in MySQL

I have this table:
And I need:
Where:
Complete have all records with same _legajo and _count > 0
Zero have all records with same_legajo and _count = 0
Track have all records with same _legajo, some records with _count 0 and some with _count >
My table is 20k records
I working on PHP and MySQL
some ideas?
You could first select MIN and MAX for each _legajo:
SELECT _legajo, MIN(_count), MAX(_count)
FROM signups
GROUP BY _legajo;
If MAX is zero, then it naturally belongs to the zero category. If MIN is larger than zero then it belongs to complete category (MAX is naturally larger than zero then). If MIN is zero and MAX isn't, then it's in track.
Then you can just use SUM to determine the counts with the conditions:
SELECT
SUM(CASE WHEN min>0 THEN 1 ELSE 0 END) as complete,
SUM(CASE WHEN max=0 THEN 1 ELSE 0 END) as zero,
SUM(CASE WHEN min=0 AND max>0 THEN 1 ELSE 0 END) as track
FROM (SELECT _legajo, MIN(_count), MAX(_count)
FROM signups
GROUP BY _legajo) a;

Struggling With DQL and Case When Expression

I am attempting the following query and am having some trouble with the count(CASE WHEN r.status=2 THEN 1 ELSE 0 END) part.
I really need to capture the count of status's where they are equal to "complete". I tried the following but I keep getting: Expected Doctrine\ORM\Query\Lexer:T_FROM, got '.'
can someone help?
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
'SELECT count(r.rpId) AS referralCount, count(CASE WHEN r.status=2 THEN 1 ELSE 0 END) as referralCompleted, p.firstName, p.lastName, p.npi, u.username
FROM MainReferralCaptureBundle:Referral r, MainReferralCaptureBundle:Physician p, MainUserBundle:User u
WHERE r.valid = 1
AND r.rpId = p.id
AND r.submittedBy = u.id
AND r.createdDate BETWEEN :startdate AND :enddate
GROUP BY p.id')
->setParameter('startdate', $form->get('startdate')->getData())
->setParameter('enddate', $form->get('enddate')->getData());
You're not grouping by all non-aggregate fields from your SELECT statement. That doesn't cause an error in some rdbms but it does cause results to be rubbish.
Additionally:
count(CASE WHEN r.status=2 THEN 1 ELSE 0 END)
Will count all records due to the ELSE 0. Remove the ELSE altogether and it will only count when the condition is met. Likewise you could change the ELSE 0 to ELSE NULL. NULL is excluded from aggregates. You could also change COUNT() to SUM().
That's all I notice from the query itself, not sure what the error you're getting is about.

MySQL alias calculation

It confuses me.. total left calculation seems doesn't work.
I am trying to get the total voucher and get total used and the total left.
please help.
SELECT
(IFNULL(SUM(value), 0)) AS total_voucher,
(
SELECT
IFNULL(SUM(value), 0))
FROM
voucher_history
WHERE
idUser = 1 AND isUsed = 1 AND DATE(FROM_UNIXTIME(datetime)) = '2014-03-04'
) AS total_used,
(total_voucher-total_used) AS total_left
FROM
voucher_history
WHERE
idUser = 1 AND isUsed = 0 AND DATE(FROM_UNIXTIME(datetime)) <= '2014-03-05'
You can do this with conditional aggregation, rather than using a subquery:
SELECT coalesce(SUM(value), 0)) AS total_voucher,
sum(case when is_used = 1 then value else 0 end) as total_used,
sum(case when is_used = 1 then 0 else value end) as total_left
FROM voucher_history
WHERE idUser = 1 AND DATE(FROM_UNIXTIME(datetime)) <= '2014-03-05';
Your query has the problem that it is trying to use column aliases (total_voucher and total_used) in the same select statement. SQL does not support this. You would need to use a subquery to get that functionality.

Categories