getting maximum number of occurrences along with count in group by - mysql

I have a table which looks like this
question_id response
1 yes
1 yes
2 agree
1 no
3 disagree
2 agree
2 disagree
I want my query to return
question_id max_response max_response_count total_responses
1 yes 2 3
2 agree 2 3
3 disagree 1 1
The query
SELECT question_id,
max(response),
count(max(response)),
count(*)
FROM response
GROUP BY question_id
gives Invalid use of group function error.
Which query should I place to get the above output.

Try this
SELECT T.question_id,Max(MR) max_response,MAX(CR)max_response_count,(Select Count(question_id) from response where question_id = T.question_id)total_responses
FROM
(SELECT question_id,max(response) MR,count(response) CR
FROM response group by question_id,response
)T
GROUP BY T.question_id
Fiddle Demo
OP:
+--------------------------------------------------------------------+
|QUESTION_ID | MAX_RESPONSE | MAX_RESPONSE_COUNT |TOTAL_RESPONSES |
+--------------------------------------------------------------------+
| 1 | yes | 2 | 3 |
| 2 | disagree | 2 | 3 |
| 3 | disagree | 1 | 1 |
+--------------------------------------------------------------------+

SELECT count(*) AS total_responses ,
question_id ,
count(max(response)) AS max_response_count
FROM response
GROUP BY question_id ,
response

I have updated my query by looking your sqlfiddle data. please try now:
create table tableA(question_id int,response varchar(50));
insert into tableA values(1,'yes'),(1,'yes'),(2,'agree'),(1,'no'),(3,'disagree'),(2,'agree'),(2,'disagree');
SELECT question_id,
max(response) AS max_response,
(select count(response) from tableA b where a.response= b.response and a.question_id= b.question_id ) as max_response_count,
count(*) AS count_response
FROM tableA a
GROUP BY question_id
I tried and get the result as expected..

Related

sql sorting inside group by with two column

My table:
id | request | subject | date
1 | 5 | 1 | 576677
2 | 2 | 3 | 576698
3 | 5 | 1 | 576999
4 | 2 | 3 | 586999
Need to select unique records by two columns(request,subject) with showing last inserted id's.
My query:
SELECT *,MAX(id)
FROM `tbl`
GROUP BY CONCAT(`request_id`, `subject_id`)
HAVING (COUNT(`request_id`)>1 order by MAX(id) desc
But results:
id | request | subject | date
2 | 2 | 3 | 576698
1 | 5 | 1 | 576677
How to get records with id's 3 and 4 ?
Try this:
SELECT MIN(id) id, request, subject, MAX(`date`) `date`
FROM `tbl`
GROUP BY request, subject;
See it run on SQL Fiddle.
You can try this.
SELECT T.*
FROM T
INNER JOIN
(
SELECT MAX(`ID`) as ID,`request`,`subject`
FROM T
GROUP BY `request`,`subject`
HAVING COUNT(`ID`) > 1
)AS T1 ON T.ID = T1.ID
SQLFiddle
Thanks for all. My result is
SELECT MAX(id), id, request, subject, date
FROM `tbl`
GROUP BY request, subject having count(request)>1 order by MAX(id) desc

mysql group by but only group if second row is the same

im wondering what the smartest way is to group my mysql results... I have the following table structure:
- id
- userId
- status (values from 1-100)
Lets say with the following content:
1 | 1 | 10
2 | 1 | 10
3 | 1 | 15
4 | 2 | 15
5 | 3 | 10
Now I want to group all results by user but only for each status. So the results im looking for should be:
1 | 1 | 10
3 | 1 | 15
4 | 2 | 15
5 | 3 | 10
Hope you understand want im looking for...
Best
Tassilo
If you need the id, then a GROUPing query is needed; this will produce the results you shown:
SELECT MIN(id), userId, status
FROM your_table
GROUP BY userId, status
;
If you don't need the id, then GROUPing is not the best tool, use DISTINCT instead; like so:
SELECT DISTINCT userId, status
FROM your_table
;
The topic of this question say "Group only if next row is the same" in that case I would do something like this:
create table USER_(id integer, UserId integer, status integer);
insert into USER_ values(1,1,10);
insert into USER_ values(2,1,10);
insert into USER_ values(3,1,115);
insert into USER_ values(4,2,115);
insert into USER_ values(5,3,10);
insert into USER_ values(6,1,10);
select min(a.id)as id, a.userId, a.status ,count(*) from USER_ a join USER_ b
on a.userid = b.userid and a.id = b.id-1 group by a.userId,a.status;
id | userid | status | count
-----+--------+--------+-------
1 | 1 | 10 | 2
If I look at the explanation for the question here then, I would do something like this:
select min(a.id) as id, a.userId, a.status from USER_ a
group by a.userId,a.status order by a.userid,status;
id | userid | status
----+--------+--------
1 | 1 | 10
3 | 1 | 15
4 | 2 | 15
5 | 3 | 10
Please correct if I have a wrong understanding of the question

MySQL count per item

I'm currently trying to make a mysql query that will count the number of zeros and ones per item, in the following way:
Table:
ID | PollID | Value
------------------------------------
1 | 1 | 1
2 | 1 | 1
3 | 2 | 0
4 | 2 | 1
5 | 1 | 0
And the result I want is:
Poll | one | zero
----------------------------------
1 | 2 | 1
2 | 1 | 1
Thanks for the help!
This is the shortest possible answer in MySQL because it supports boolean arithmetic.
SELECT PollID,
SUM(value = 1) AS `One`,
SUM(value = 0) AS `Zero`
FROM tableName
GROUP BY PollID
SQLFiddle Demo
select z.pollid,z.ones,s.zeros
from (select a.pollid,count(a.value) as ones from test a
where a.value=1
group by a.pollid) z
left join
(select b.pollid,count(b.value) as zeros from test b
where b.value=0 group by b.pollid) s
on z.pollid=s.pollid;
try this
select table.pollid,
Switch(table.value Like 1, 1)AS one,
Switch(table.value Like 0, 1)AS zero
from table
group by pollid

How to make a query to GROUP BY x DESC

The following SELECT statement
select *
from messages
where receiverID = '5'
group BY senderID
order by id DESC
database:
id | senderID | receiverID | message
1 | 245 | 5 | test 1
2 | 89 | 5 | test 2
3 | 79 | 5 | test 3
4 | 245 | 5 | test 4
5 | 245 | 5 | test 5
For senderID=245 I expected to return the row with id=5 , but it dosent it returns row with id=1, but i want the last row. How to achieve that ?
returns:
id | senderID | receiverID | message
1 | 245 | 5 | test 1
2 | 89 | 5 | test 2
3 | 79 | 5 | test 3
Ohh I made it :D
so this is the code that worked,for anyone with similar question
SELECT * FROM ( SELECT * FROM messages WHERE
receiverID = '5' ORDER BY id DESC) AS m GROUP BY senderID ORDER BY id DESC
This is not possible. You have to do something like:
[...] WHERE `id` = (SELECT MAX(`id`) FROM `messages` WHERE `receiverID` = '5')
Personally I'd consider a subquery, something along the lines of this should do the job for you
SELECT messagesOrdered.*
FROM (
SELECT *
FROM messages
WHERE receiverID = '5'
ORDER BY id DESC
) AS messagesOrdered
GROUP BY senderID
You may wish to check what keys you have set up depending on how large the table is.
The problem with using MAX is that if you use MAX on the id field then it will get the number you are looking for, however using MAX on another field does not get the data that matches that id. Using the subquery method, the inner query is doing the sorting and then the GROUP on the outside will group based on the order of rows in the inner query.
SELECT * FROM messages m
JOIN
( SELECT senderID, MAX(id) AS last
FROM messages
WHERE receiverID = '5'
GROUP BY senderID ) mg
ON m.id = mg.last
Not sure I understand your question completely, but it sounds to me like you want:
select max(id),
senderId,
max(receiverId),
max(message)
from messages
where receiverID = '5'
group BY senderID
order by id DESC
Note that you need to include message into your aggregate as well, otherwise you'll get unpredicatable results (other DBMS wouldn't allow leaving out the max(message) but MySQL will simply return a random row from the group).
Here it goes mine :)
select m1.* from messages m1
left join messages m2
on m1.senderid = m2.senderid and m1.id < m2.id
where m2.id is null and receiverID = '5'
Given your example this would return:
+----+----------+------------+---------+
| ID | SENDERID | RECEIVERID | MESSAGE |
+----+----------+------------+---------+
| 2 | 89 | 5 | test 2 |
| 3 | 79 | 5 | test 3 |
| 5 | 245 | 5 | test 5 |
+----+----------+------------+---------+

How to return multiple rows when compared to multiple values?

So my current table looks like this :
| UserID | QuestionID | GameID |
| 1 | 30 | 2 |
| 1 | 30 | 3 |
| 2 | 30 | 4 |
| 3 | 30 | 2 |
| 4 | 30 | 3 |
How would I return all the rows where the same UserID has a value for GameID 1, 2, 3 and 4? Basically trying to return all the users who have played Game 1, 2, 3 and 4
Assuming no duplicates of game id..
Select userID
from table
where gameID in (1,2,3,4)
group by UserID
having count(GameID) = 4
If I get the answer correct, it might be:
SELECT p.* FROM poll AS p WHERE p.UserID = <your_user_id> AND p.GameID IN (1,2,3,4)
or you are seeking for:
SELECT p.*, GROUP_CONCAT(p.GameID) FROM poll AS p WHERE p.UserID = <user_id> GROUP BY p.GameID
Assuming the tables are normalized and joined properly, simply use a WHERE clause:
WHERE colname = value1 OR colname = value2 ...
or use the In operator
WHERE colname = In (value,value...)
http://beginner-sql-tutorial.com/sql-logical-operators.htm
SELECT
UserID
FROM (
SELECT
UserID,
GROUP_CONCAT(GameID ORDER BY GameID) as Games
FROM some_table
GROUP BY UserID
) AS baseview
WHERE Games="1,2,3,4"
Please understand, this is a performance killer - it creates the GROUP_CONCAT for all users.