Count unique ids on right table - mysql

I have a mysql statement as follows:
SELECT * FROM class_members WHERE class_id = 1;
Which returns the following result:
class_id | user_id
1 | 2
1 | 1
1 | 3
1 | 5
I want to count all the unique user_ids per class.
Can anyone help?
Thank you

SELECT class_id, COUNT(DISTINCT user_id)
FROM mytable
GROUP BY
class_id

Related

How to find exact row match using IN in Where clause?

I have two tables tbl_group AND tbl_members.
Here is snapshot of both the tables.
+----+------------+
| id | groupTitle |
+----+------------+
| 1 | Group 1 |
| 2 | Group 2 |
+----+------------+
+----+---------+--------+
| id | groupId | userId |
+----+---------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
+----+---------+--------+
Now i want to create one more group with userId 3,2 but before that i want to check that is there any group which has same member 3 and 2 not any other.
i have used IN clause but it does not work.
SELECT DISTINCT groupId
FROM tbl_members
WHERE userId IN (3,2)
It is returning both the group though result would be empty.
We can try using INSERT INTO ... SELECT with an EXISTS clause which asserts that userId of 2/3 does not already occur for any group.
INSERT INTO tbl_members (groupId, userId)
SELECT groupId, userId
FROM (
SELECT 3 AS groupId, 2 AS userId UNION ALL SELECT 3, 3
) t
WHERE NOT EXISTS (SELECT 1 FROM tbl_members
WHERE userId IN (2, 3)
GROUP BY groupId
HAVING MIN(userId) <> MAX(userId));
You would also have to insert a new record into the tbl_group table for the new group.
SELECT DISTINCT groupId FROM tbl_members WHERE userId = '2'
INTERSECT
SELECT DISTINCT groupId FROM tbl_members WHERE userId = '3'
One way is to use conditional aggregation based filtering using GROUP BY with HAVING clause. We will use a query to get the groupId value which has userId values of 3 and 2 only. If the query does not return any such value; this implies that no such Group exists; hence you can create the group.
SELECT
groupId
FROM tbl_members
GROUP BY groupId
HAVING SUM(userId = 2) AND /* userID 2 exists */
SUM(userId = 3) AND /* userID 3 exists */
NOT SUM(userId NOT IN (2,3)) /* No other userId exists (other than 2,3) */
This returns groupId's where only 2 AND 3 are in the group.
Count of all userId's in the group - sum of 1 for records where userId = 2 or 3 has to be 0 if there are no other userid's in the group.
Sure this will work only if 2 and 3 don't repeat itself in the same group.
SELECT groupId
FROM tbl_members
GROUP BY groupId
HAVING COUNT(userId)-SUM(userId IN (2,3)) = 0
First inner query will decide all fetched groups have only two members that will reduce set of unnecessary records then second inner query take that group id and check whether there is no other member then 3,2 in that group, and finally whole query will give group id which has only 3,2 as member.
SELECT groupId
FROM tbl_members m
WHERE m.userId IN (3,2) AND
(SELECT COUNT(memberId) FROM tbl_members mmm WHERE mmm.groupId=m.groupId)=2 AND
(SELECT COUNT(memberId) FROM tbl_members mm WHERE mm.groupId=m.groupId AND
m.userId NOT IN (3,2))<=0
GROUP BY groupId
I think this query will give the group of values in userid (2,3), groupid (2,3)
from the table
SELECT count(1), userid ,groupid FROM tbl_members
WHERE groupid IN (3,2) and userid in (3,2)
group by userid, groupid;

Select previous record from row

Example
id |u_id
1 | 1
2 | 1
3 | 2
4 | 1
5 | 2
6 | 3
I know, the id 4 has u_id of 1, but I want to select the last row having u_id 1 before that with id 4 i.e. I want to select the row with the id 2.
Note that I don't know this id.
How can I achieve that?
This is what the result should look like:
id |u_id
2 | 1
4 | 1
select * from table where uid=1 order by id desc limit 2
This may help you.
SELECT * FROM ( SELECT * FROM yourTable WHERE u_id=1 ORDER BY id DESC LIMIT 2) AS tab ORDER BY tab.id ASC
Finally figured out the correct sql query for it.
SELECT * FROM table WHERE u_id = 1 AND (id = 4 OR id < 4) ORDER BY id DESC LIMIT 0,2
If you are using a fairly recent version of MySQL, what you need is the LAG() windowed function:
SELECT id,
u_id,
LAG(id) OVER W AS prev_id
FROM MyTable
WINDOW w AS (PARTITION BY u_id ORDER BY id)
ORDER BY id, u_id;
It will produce a result like this:
id |u_id |prev_id
1 | 1 | null
2 | 1 | 1
3 | 2 | null
4 | 1 | 2
5 | 2 | 3
6 | 3 | null
You can play with the query here.
As your title states:
select previous record from row
The following gives you every row that comes prior to a 2, and will work with more than just the data you've shown in your example:
SELECT *
FROM example
WHERE id IN (
SELECT id - 1
FROM example
WHERE u_id = 2);
[SEE DEMO HERE]

MySQL - select from a set of unique values

I have a following setup:
---------------------
| user_id | list_id |
---------------------
| 1 | 1 |
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
---------------------
I need to select user_id's by list_id, but only those which are unique in the table. So, in my example it should be only user_id's 2 and 3.
What should I add to
select user_id from table where list_id=2 ?
Please help, I'm really stuck...
Thanks
Group by the user_id and take only those having at least one list_id = 2 and in total only one record of this user_id
select user_id
from table
group by user_id
having sum(list_id = 2) > 0
and count(*) = 1
Try this:
select user_id from table group by user_id having count(*) =1
We can use below query
select user_id ,count(*)
from table
GROUP BY
user_id
HAVING
COUNT(*) = 1
select user_id from table group by user_id having count(*)=1;

How to fetch count of every classid from DB table in Mysql see below for detail

I have this table structure
| id | classid | contextid |
----------------------------
1 2 2
2 3 1
3 2 1
4 3 1
5 1 2
5 1 4
How to fetch count of every classid from DB table in Mysql I need a select query for it?
Count of every classid... do you mean something like this:
SELECT classid, COUNT(*) as cnt FROM tbl_name GROUP BY classid
SELECT classid, COUNT(*) FROM table1 GROUP BY classid;
SELECT classid, COUNT(classid) classid_count FROM table_name GROUP BY classid;

How to get total occurrence of a value within its own query?

Let's say we have this query
SELECT * FROM table
And this result from it.
id | user_id
------------
1 | 1
------------
2 | 1
------------
3 | 2
------------
4 | 1
How could I get the count of how often a user_id appears as another field (without some major SQL query)
id | user_id | count
--------------------
1 | 1 | 3
--------------------
2 | 1 | 3
--------------------
3 | 2 | 1
--------------------
4 | 1 | 3
We have this value currently in code, but we are implementing sorting to this table and I would like to be able to sort in the SQL query.
BTW if this is not possible without some major trick, we are just going to skip sorting on that field.
You'll just want to add a subquery on the end, I believe:
SELECT
t.id,
t.user_id,
(SELECT COUNT(*) FROM table WHERE user_id = t.user_id) AS `count`
FROM table t;
SELECT o.id, o.user_id, (
SELECT COUNT(id)
FROM table i
WHERE i.user_id = o.user_id
GROUP BY i.user_id
) AS `count`
FROM table o
I suspect this query as not being a performance monster but it should work.