MySql, use group by with a WHERE clause - mysql

I want to add a WHERE clause to my statement, but the problem is,
when I add the WHERE clause, I get an error "Invalid use of group function".
I also tried to replace the WHERE clause and write the condition into the
JOIN .. ON part, but the error is still there.
I want to add the condition so that only the rows " SUM(res.ReservationID) = 2" are returned.
-- works but we only want to get the rows in which the SUM = 2
SELECT ctr.ID, ctr.LastName, ctr.FirstName, SUM(res.ReservationID) as ReservierteSitze
FROM customer as ctr
INNER JOIN reservation AS res ON ctr.ID = res.CustomerID
Group by ctr.ID;

SELECT ctr.ID, ctr.LastName, ctr.FirstName, SUM(res.ReservationID) as ReservierteSitze
FROM customer as ctr
INNER JOIN reservation AS res ON ctr.ID = res.CustomerID
Group by ctr.ID
HAVING ReservierteSitze = 2;
The HAVING clause is like a where clause for the GROUP BY (applies to the groupings)
You can still have a WHERE clause before the GROUP BY clause, but that only applies to the individual rows before the grouping.

having(Aggregation function condition processing)

Related

View created from valid SQL statement returns error "#1242 - Subquery returns more than 1 row"

When I run the below SQL statement, it correctly shows me what I expect:
SELECT Users.idQuiz as ThisIDQuiz,Rounds.RoundNr as ThisRoundNr, Questions.QuestionNr as ThisQuestionNr, Answer as ThisAnswer, Questions.QuestionScore AS QuestionScoreMax,AnswerCorrect,
(SELECT COUNT(*) as "Aantal Ploegen met dit antwoord"
FROM `Answers`
JOIN Questions on Answers.idQuestion = Questions.idQuestion
JOIN Rounds on Questions.idRound = Rounds.idRound
JOIN Users on Users.idUser = Answers.idUser
where (Users.idQuiz = ThisIDQuiz AND Rounds.RoundNr = ThisRoundNr AND Questions.QuestionNr=ThisQuestionNr AND Answers.Answer = ThisAnswer )
GROUP BY Users.idQuiz,Rounds.RoundNr, Questions.QuestionNr,Answer
) as NrOfTeamsWithThisAnswer,
(SELECT COUNT(*)
FROM Users
WHERE ((Users.idQuiz = ThisIDQuiz) AND (Users.UserType = 0))
) As TotalNrOfTeams,
AnswerCorrect *((Select TotalNrOfTeams)- (SELECT NrOfTeamsWithThisAnswer))as ScoreForThisAnswer
FROM `Answers`
JOIN Questions on Answers.idQuestion = Questions.idQuestion
JOIN Rounds on Questions.idRound = Rounds.idRound
JOIN Users on Users.idUser = Answers.idUser
WHERE Questions.QuestionType = 5
GROUP BY ThisAnswer
ORDER BY ThisIDQuiz, ThisRoundNr, ThisQuestionNr, ThisAnswer;
See Results of the query for what the result looks like.
I then create a VIEW from this statement. The view is created fine, but when I open it, I get the error "#1242 - Subquery returns more than 1 row".
I tried dropping and recreating the view, same result.
When I use the exact same SQL statement but without the penultimate line (GROUP BY ThisAnswer), it works fine (i.e. I can create the view and it opens without an error). This second view suits my purposes fine, so I can continue, but just out of curiosity: can someone explain this behaviour?
I use phpMyAdmin version 5.1.3 to do my SQL manipulations.
As #NickW asks, the statement GROUP BY ThisAnswer expects you to have an aggregate function (i.e. count, avg, max, min, etc.) somewhere in that main SELECT. Having a GROUP BY without an aggregate function will create errors. Either add the aggregate function, or remove the GROUP BY statement in the main (outermost) SELECT.

Subtract the sum of one column from another table's column

What I have tried:
SELECT requestformtbl.employee_name, requestformtbl.request_type, requestformtbl.total_day,
requestformtbl.request_status, requestformtbl.admin_remark, requestformtbl.confirmed_by, requestformtbl.date_confirmed, requesttbl.max_allotment,
(requesttbl.max_allotment - sum(requestformtbl.total_day)) as Available from requestformtbl inner join requesttbl on
requestformtbl.request_type = requesttbl.request_type;
error: Column 'requestformtbl.employee_name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
If requestttbl.request_type="Vacation Leave" has requesttbl.max_allotment=20,
when a new entry in requestformtbl is inserted with requestformtbl.request_type="Vacation Leave" and requestformtbl.total_day=5
I want to get the remaining available leave
You can get the results you want without using a GROUP BY by using a correlated subquery to get the sum of the employees used days:
SELECT rft.employee_name,
rft.request_type,
rft.total_day,
rft.request_status,
rft.admin_remark,
rft.confirmed_by,
rft.date_confirmed,
rt.max_allotment,
rt.max_allotment - (select sum(total_day)
from requestformtbl rft2
where rft2.employee_name = rft.employee_name) as Available
from requestformtbl rft
inner join requesttbl rt on rft.request_type = rt.request_type;
Note I've used table aliases to make the query more readable.

How to get count of distinct rows in MySQL?

I have used the following query:
select tblclass.classname,tblattendance.id
from tblclass,tblattendance
where tblclass.classcode=tblattendance.classcode
and tblattendance.attdate='2013-07-01'
Output of this query is as follows:
Now what I want is rather than the above result I want count of different classes like IB-2,IC-5.
Please tell me what modifications do I need to made in my query to get the desired result
Use the Group By SQL clause and add the aggregate function Count
select tblclass.classname, Count(tblattendance.id) as counter
from tblclass,tblattendance
where tblclass.classcode=tblattendance.classcode and tblattendance.attdate='2013-07-01'
group by tblclass.classname
Try this
select count(tblattendance.id),tblclass.classname from tblclass,tblattendance
where tblclass.classcode=tblattendance.classcode and tblattendance.attdate='2013-07-01'
group by tblclass.classname
Use COUNT() function for that with GROUP BY. Also use JOIN.
SELECT tc.classname, COUNT(tc.classname) AS COUNTS
FROM tblclass tc
JOIN tblattendance tt
ON tc.classcode = tt.classcode
WHERE tt.attdate='2013-07-01'
GROUP BY tc.classname

count(*) in mysql returning only one record

I want to count how many records from another table in the same select statement , i used Left join
and in the select statement i put count(ag.*)
see the
Example :
$q = Doctrine_Query::create()
->select("a.answer_id,a.date_added , count(ag.content_id) AS agree_count")
->from('Answer a')
->leftJoin("a.Agree ag ON a.answer_id = ag.content_id AND ag.content_type = 'answer' ")
->where('a.question_id= ? ', $questionId)
But its only returning the first record, can i Fix that? or to make another table and make it only for counting ?
You are missing a GROUP BY in your query.
More infos here.
When you don't have a GROUP BY clause, it's normal to get only one row.
Count(*) will only return one record if you don't use Group By. You are asking it to count all the records, so there can be only one result.
The count() SQL function changes how results are returned from the database - without a GROUP BY the database will only return one record, regardless of other colums in the SELECT.
if you add:
group by a.answer_id
to the end of your SQL query, that might DWYM.

Getting "#1111 - Invalid use of group function" without using GROUP in MySQL

$qb = $this->createQueryBuilder('t');
return $qb
->join('t.customers', 'c')
->where($qb->expr()->eq('t.user', $user->getId()))
->andWhere($qb->expr()->gt($qb->expr()->count('c'), 0))
->orderBy('t.name')->getQuery()->getResult();
The above query (Doctrine2 generated one) is giving me this error:
#1111 - Invalid use of group function
but the strange thing is i'm not using GROUP BY. Any help is much appreciated, thanks.
SELECT t0_.id AS id0,
t0_.slug AS slug1,
t0_.name AS name2,
t0_.description AS description3,
t0_.user_id AS user_id4
FROM tag t0_
INNER JOIN customers_tags c2_ ON t0_.id = c2_.tag_id
INNER JOIN customer c1_ ON c1_.id = c2_.customer_id
WHERE t0_.user_id = 1 AND COUNT(c1_.id) > 0
ORDER BY t0_.name ASC
You are using an aggregate function count() in the where clause which is not allowed.
Conditions on aggregate functions need to go into a HAVING clause
....
WHERE t0_.user_id = 1
HAVING count(c1_.id) > 0
And of course you'll need to use a GROUP BY to get correct results (although MySQL will probably let you get away with not using a GROUP BY - but then the results are unpredictable)
There is no need in joins and havings. Simply use SIZE function:
$qb->where('SIZE(t.customers) = 0');
This will give you all rows without attached customers
"Count" can not be used in where without group by, count is "group function"