Select record table mysql - mysql

I'm working on a small search engine project and I need some help with a SQL query. My table looks like this (example):
user_id | group_id
---------------------------
1 | 2
2 | 2
2 | 3
3 | 2
I would like to look for : user_id who has group_id = 2 and 3
So a possible result would be:
user_id | group_id
---------------------------
2 | 2
2 | 3
How should the select query look like?

I will suppose your table name is users and we will select only two columns user_id and group_id from the users table
SELECT user_id, group_id FROM users WHERE group_id IN (2, 3);

You want something like this:
SELECT *
FROM your_table
WHERE user_id IN (
SELECT DISTINCT user_id
FROM your_table
WHERE group_id IN (2,3)
GROUP BY user_id
HAVING COUNT(user_id) > 1 )
Check demo.
EDIT. I have modified my answer to below to be more accurate as pointed out by #ysth:
SELECT DISTINCT user_id,
group_id
FROM usergroups
WHERE user_id IN (
SELECT DISTINCT user_id
FROM (SELECT DISTINCT user_id,
group_id
FROM usergroups ) g
WHERE group_id IN (2,3)
GROUP BY user_id
HAVING COUNT(user_id) > 1 )
Check demo.

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;

Mysql Query to find the last transaction date with the purchased item from Purchase_history table

Table: purchase_history having all details of users
Fields are : id,uid, purchase_date, item_id, item_size, item_color
where id is a primary key.
There are many rows for an similar uid. e.g.
id | uid | purchase_date | item_id | item_size | item_color
1 | 200 | 2016-10-22 | 1021 | 3 | red
2 | 122 | 2016-08-02 | 21 | 1 | black
3 | 200 | 2016-05-01 | 222 | 1 | blue
4 | 101 | 2016-01-07 | 102 | 1 | red
So now I want a single query to get the last transaction date, item_id and uid group by uid. I used below query:
select uid, max(purchase_date), item_id from purchase_history group by uid;
it gives me correct uid and purchase date but the item id is not picked from the last row. It is coming from the first row. Is there any way that we can find the item id from the last row with uid and purchase_date?
Try this:
select uid, max(purchase_date) as date, item_id from purchase_history group by uid ORDER by date desc,item_id desc
Make sure that you item_id type is an integer.
You can find max of purchase date for each user in a subquery and join it with the main table like so:
select t1.uid, t1.purchase_date, t1.item_id
from purchase_history t1
inner join (
select uid, max(purchase_date) purchase_date
from purchase_history
group by uid
) t2 on t1.uid = t2.uid
and t1.purchase_date = t2.purchase_date;
NOTE: It'll give multiple rows for a uid, if there are rows with multiple max dates.
Use correlated subquery:
SELECT uid, purchase_date, item_id
FROM purchase_history p1
WHERE purchase_date = (
SELECT MAX(purchase_date)
FROM purchase_history p2
WHERE p2.uid = p1.uid
);
try this query
select * from (select * from purchase_history order by purchase_date asc) purchase_history group by uid;

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;

Count unique ids on right table

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

SELECT all the newest records distinct

i have table structure like this
sn | person_id | image_name |
1 | 1 | abc1.jpb
2 | 1 | aa11.jpg
3 | 11 | dsv.jpg
4 | 11 | dssd.jpg
5 | 11 | sdf.jpg
I need distinct person_id newest row as following
2 | 1 | aa11.jjpb
5 | 11 | sdf.jpg
IT is possible ?
SELECT * FROM yourtable GROUP BY person_id ORDER BY sn DESC
Essentially you want to select all records from your table. Then it is grouped by the person_id (limiting the result to 1 per person id)... Ordering by SN decending means that it will return the most recent (highest) sn
Update: (and verified)
SELECT * FROM (SELECT * FROM stackoverflow ORDER BY sn DESC) a GROUP BY person_id ORDER BY sn
SELECT * FROM table GROUP BY person_id HAVING MAX(sn)
EDIT
SELECT f.*
FROM (
SELECT person_id, MAX(sn) as maxval
FROM table GROUP BY person_id
) AS x INNER JOIN table AS f
ON f.person_id = x.person_id AND f.sn = x.maxval;
where table is your table name.
SELECT * FROM table a WHERE a.`id` = ( SELECT MAX(`id`) FROM table b WHERE b.`person_id` = a.`person_id` );
What you are doing inside the parenthesis is selecting the max id for the rows that have that distinct person_id. So for each unique person_id you are getting the most recent entry.