Basically, as the question states, I am looking for the easiest and most straight forward way of getting counts based on unique values.
Here is my data set:
id | item_id | user_id
1 | 10 | 123
2 | 10 | 123
3 | 10 | 123
4 | 11 | 123
5 | 12 | 123
6 | 10 | 456
7 | 10 | 789
8 | 12 | 456
Ideally, when I run the query I should get the following:
count | user_id
3 | 123
2 | 456
1 | 789
Where even though user 123 has 5 items to their name, the really only purchased 3 unique items. Is this really straight forward and I'm just missing it completely? Here is what I have currently:
SELECT count(user_id) AS count, item_id, user_id
FROM table
GROUP BY item_id, user_id
HAVING count > 1
ORDER BY count DESC
This is producing the opposite of what I want:
count | user_id
5 | 123
2 | 456
1 | 789
Thanks in advance! And if this has been answered already, please point me in that direction.
You can count distinct item ids and then group by the user id:
SELECT
COUNT(DISTINCT item_id) AS count,
user_id
FROM
event_assigned
GROUP BY
user_id
ORDER BY
count DESC
Related
I apologize in advanced if I am not explaining this correctly. I can barely explain it in english terms, let alone in a mysql query.
I am trying to get the list of response_set_ids that have more than 1 record for a question_id.
This is an example of my data:
+----+-----------------+-------------+-----------+
| id | response_set_id | question_id | answer_id |
+----+-----------------+-------------+-----------+
| 1 | 10 | 1 | 4 |
| 2 | 10 | 2 | 5 |
| 3 | 10 | 3 | 6 |
| 4 | 10 | 3 | 7 |
| 5 | 11 | 1 | 8 |
| 6 | 11 | 2 | 9 |
| 7 | 11 | 3 | 10 |
+----+-----------------+-------------+-----------+
I would like to have a query that would return me a list response_set_ids, and in this particular example, I would expect to get returned 10 because that response_set has question_id -> 3 showing up more than once.
Please let me know if you need any further information to help me.
I have tried this:
select response_set_id, count(question_id) from responses group by response_set_id;
But that only gives me the counts of questions per response_set.
Thank you in advanced!
The simplest method doesn't use a subquery:
SELECT DISTINCT response_set_id
FROM responses
GROUP BY response_set_id, question_id
HAVING COUNT(*) > 1;
This is one of the very, very few instances where select distinct is used (appropriately) with group by.
select distinct response_set_id from (
select response_set_id , question_id
from
responses
group by
response_set_id, question_id
having count(*)>1) a
I believe this question has been asked before but I cannot add comments at my current rep:
SELECT DISTINCT response_set_id
FROM responses
GROUP BY question_id
HAVING COUNT(question_id) > 1
I'm sorry for fuzzy title of this question.
I have 2 Tables in my database and want to count records of first_table using "group by" on a foreign key id that exists in a column of second_table (which stores ids like array "1,2,3,4,5").
id | name | fk_id
1 | john | 1
2 | mike | 1
3 | jane | 2
4 | tailor | 1
5 | jane | 3
6 | tailor | 5
7 | jane | 4
8 | tailor | 5
9 | jane | 5
10 | tailor | 5
id | name | fk_ids | s_fk_id
1 | xxx | 1,5,6 | 1
2 | yyy | 2,3 | 1
3 | zzz | 9 | 1
4 | www | 7,8 | 1
Now i wrote the following query but it not working properly and displays wrong numbers.
I WANT TO:
1-Count records in first_table group by "fk_id"
2-Sum the counted records which exists in "fk_ids"
3-Display the sum result (sum of related counts) grouped by id.
symbol ' ' means ``.
select sum(if(FIND_IN_SET('fk_id', 'fk_ids')>0,'count',0) 'sum', 'count', 'from'.'fk_id', 'second_table'.* FROM 'second_table'
LEFT JOIN
(
SELECT 'fk_id', count(*) 'count'
FROM 'first_table'
group BY 'fk_id'
) AS 'from'
ON FIND_IN_SET('fk_id', 'fk_ids')>0
WHERE 'second_table'.'s_fk_id'=1
GROUP BY 'id'
ORDER by 'count' DESC
This table has many data and we have no plan to change the structure.
Edit:
Desired output:
id | name | sum
1 | xxx | 7 (3+4+0)
2 | yyy | 2 (1+1)
3 | zzz | 0 (0)
4 | www | 0 (0+0)
After two holidays i came back to work and found out that the "FIND_IN_SET" function is not working properly with space contained string.
And the problem is that i was ignored the spaces too, (same as this question)
Finnaly this query worked:
select sum(`count`) `sum`, `count`, `from`.`fk_id`, `second_table`.* FROM `second_table`
LEFT JOIN
(
SELECT `fk_id`, count(*) `count`
FROM `first_table`
group BY `fk_id`
) AS `from`
ON FIND_IN_SET(`fk_id`, replace(`fk_ids`,' ',''))>0
WHERE `second_table`.`s_fk_id`=1
GROUP BY `id`
ORDER by `count` DESC
And the magic is replace(fk_ids,' ','')
I have a table called options with the following data:
id|content|index| question_id
----------------------------
1 | yes | 1 | 123
2 | no | 2 | 123
3 | maybe | 1 | 123
4 | yeah | 2 | 124
5 | yep | 1 | 124
6 | nope | 1 | 125
7 | no | 2 | 125
8 | yessir| 1 | 125
Each option is mapped to an MCQ question on the question_id. There cannot be duplicated indexes for a question.
I want to find out the number of options with duplicate indexes against the same question_id
Here's how I am trying to do it:
SELECT
count(index) as c,
question_id
from options
group by question_id, index having c > 1
However, I don't seem to get the result I am looking for.
I want to get the following rows called out:
id | content | index | question_id
-----------------------------------
3 | maybe | 1 | 123
8 | yessir | 1 | 125
Also, the following result set will help as well:
question_id | duplicates
-------------------------
123 | 2
125 | 2
select question_id, sum(dups) dups from (
SELECT
question_id,
option_index,
count(option_index) dups
from options
group by question_id, option_index
having count(option_index) > 1)
group by question_id;
SELECT
question_id,
count(index) as duplicates
from options
group by question_id, option_index having count(index) > 1
use count function. Aliased column c is not available in having clause.
I have a table like this:
name | day | score
------------------
John | 1 | 4
John | 2 | 5
John | 3 | 6
Marc | 1 | 7
Marc | 2 | 4
Marc | 3 | 5
Paul | 1 | 8
Paul | 2 | 2
Paul | 3 | 3
I want to get the sum of the score for each person, but only for certain days, sorted by this sum. let's say I want to get the score-sum of the 1. and 2. day, this is what I expect:
name | sum(score)
-----------------
Marc | 11
Paul | 10
John | 9
this is what failed:
SELECT name, sum(score) FROM mytable WHERE day<=2
I think I have to surround the sum(score)-part with some IF-statement, but I have no idea how.
Just add group by
SELECT name, sum(score) FROM mytable WHERE day<=2 group by name
Use sum function and group by clause for grouping the result.
query
select name,sum(score) as score
from myTable
where day in (1,2)
group by name
order by sum(score) desc;
fiddle demo
Here is a log of user activity on my project, who have each "voted" on various items, giving each item either a "1", "2" or "3" rating.
rec_id | user_id | item_id | value
-----------------------------------
1 | 1 | 2 | 3
2 | 1 | 2 | 2
3 | 2 | 1 | 1
4 | 3 | 1 | 1
5 | 3 | 2 | 2
6 | 1 | 2 | 1
7 | 1 | 4 | 2
I'm trying to return all the item_id's user_id "1" has voted on, and the last value they gave each item. So, my goal is to return the following rows from the full table above:
rec_id | user_id | item_id | value
-----------------------------------
6 | 1 | 2 | 1
7 | 1 | 4 | 2
In the first example, user_id "1" has voted on item_id "2" three times, so I want to ignore the previous instances in which user 1 has voted on it.
Here is my statement so far, but this returns "3" for the rating of item_id 2, when it should be "1":
SELECT MAX(rec_id), user_id, item_id, value
FROM logs
WHERE user_id=1
GROUP BY user_id, item_id
What do I need to add to reach my goal?
basically you just need a subquery where the rec_id is equal to the max rec_id
QUERY:
SELECT
rec_id, user_id, item_id, value
FROM logs
WHERE user_id = 1
AND rec_id IN
( SELECT
MAX(rec_id)
FROM logs
GROUP BY item_id
)
GROUP BY user_id, item_id
DEMO
OUTPUT:
+-------+---------+----------+-------+
|rec_id | user_id | item_id | value |
+-------+---------+----------+-------+
| 6 | 1 | 2 | 1 |
| 7 | 1 | 4 | 2 |
+-------+---------+----------+-------+
You get the last row usually you would use a combination of order by and LIMIT 1.
In your case I would use two seperate queries though. But I would first restructure my database to avoid religion and duplicates.strong text