mysql query find sets which element match to another sets element - mysql

My tables are like below format
User table
> id username interest_ids
> 1 Ram 1,2,3
> 2 Suja 2,3,
> 3 Rahul 2,4,5,6
> 4 nipa 1,4,6
Interest Tables Like
id name
1 Music
2 Book
3 News
4 T.V watching
5 Song
6 Dancing
7 Game
now i want to search user who have same interest.
example Nipa is a user whose interest id are 1,4,6
and interest ids match with user Ram (id 1)and Rahul(id 3)
What is mysql query so i can fetch users who has similar interest id like nipa.

If your tables were normalised properly (WHICH THEY SHOULD BE! DO IT!) and you had a user_interests table that looked like this:
create table user_interests (
user_id integer,
interest_id integer
);
Then your answer would be:
select distinct username
from users u
inner join user_interests ui
on u.id = ui.user_id
where ui.interest_id in
(select ui2.interest_id
from users u2
inner join user_interests ui2
on u2.id = ui2.user_id
where u2.username = 'Nipa'
)
and u.user_name <> 'Nipa'
As it stands, mysql can't split strings without a lot of effort that would be better spent fixing the tables.
Here's an example

Related

Get mutual relationship from database table

I have table user_follow which has only two columns: who and whom. They represent links between users when WHO follows WHOM. If two users follow each other, they are considered friends. In such case the table would contain records:
WHO WHOM
1 2
2 1
Where 1 and 2 are simply user IDs.
In order to determine if two users are friends, I have to query the table and use simple condition
SELECT COUNT(*)
FROM user_follow
WHERE (who = 1 AND whom = 2) OR (who = 2 AND whom = 1)
If I get 2 then they are friends.
But if I want to load list of all user's friends, I cannot do it that way. So i came up with sql join into itself:
SELECT uf2.whom
FROM user_follow AS uf1
LEFT JOIN user_follow AS uf2 ON uf1.who = uf2.whom
WHERE uf1.whom = ? AND uf2.who = ? ORDER BY uf2.whom
I made a dummy table to test it and it works. But I would like for someone to confirm this is the correct solution.
I think your query is correct if you supply the same parameter value for ?. I find the query below simpler to understand.
The query below lists the friends (users who follow each other) of a user:
SELECT uf1.whom
FROM user_follow AS uf1
INNER JOIN user_follow AS uf2
-- filter down to followed users
ON uf1.whom = uf2.who
-- followed users follow their followers
AND uf1.who = uf2.whom
-- the user whose friends are listed
WHERE uf1.who = ?
ORDER BY 1
;

How to JOIN SELECT from multiple tables, where the SELECTS is based on different conditions?

I have three tables. One with notes Notes, one with users Users, and one a relational table between users and notes NotesUsers.
Users
user_id first_name last_name
1 John Smith
2 Jane Doe
Notes
note_id note_name owner_id
1 Math 1
2 Science 1
3 English 2
NoteUsers
user_id note_id
1 1
2 1
2 2
2 3
Hopefully, from the select statement you can tell what I'm trying to do. I am trying to select the notes that user_id = 2 has access to but doesn't necessarily own, but also along with this I'm trying to get the first and last name of the owner.
SELECT Notes.notes_id, note_name
FROM Notes, NotesUsers
WHERE NotesUsers.note_id = Notes.note_id AND NotesUsers.user_id = 2
JOIN SELECT first_name, last_name FROM Users, Notes WHERE Notes.owner_id = Users.user_id
My problem is that because the WHERE clause for first_name, and last_name versus that for notes are different, I don't know how to query the data. I understand that this is not how a JOIN works and
I don't necessarily want to use a JOIN, but I'm not sure how to structure the statement, so I left it in there so that you can understand what I'm trying to do.
You can join Notes with NoteUsers to check for access and with Users to add the user's details to the result:
SELECT n.noted_id, n.note_name, u.first_name, u.last_name
FROM Notes n
JOIN NoteUsers nu ON n.noted_id = nu.note_id AND nu.user_id = 2
JOIN Users u ON n.owner_id = u.user_id
you need here to use a query inside the main query. MySQL will return first all the note_id that the user with user_id = 2 has access to from NoteUser, then well build the outer query to return the first_name and the last_name of the owner.
SELECT u.first_name, u.last_name, n.note_name, n.note_id
FROM Notes AS n
LEFT JOIN Users AS u ON u.user_id = n.owner_id
WHERE n.note_id IN
(SELECT nu.note_id FROM NoteUser WHERE nu.user_id = 2)

Join table on pattern match

I have been struggling with this for several hours, so any feedback or advise is very welcome.
I have three tables:
users
id name email
1 test test#test.com
2 test2 test2#test.com
pets
pet_id pet_name user_id
1 sam 2
2 sally 1
transactions
trans_id custom
1 1
2 pid2
3 pid1
OK, what I would like to do is get transaction data relating to the user. So in the 'transactions' table 'custom' value 1 would relate to 'users' with the id. Thats the simple bit...
'Transactions' with 'pid' relate to the pets id, so 'pid2' relates to sally, whose user is user id 1. So I need to join the transaction table when custom relates to the user id or if its prefixed with 'pid' and the appending value relates to the 'pet_id'.
Here's an example of the result I would like:
Transactions relating to user_id 1:
trans_id 1, custom 1
trans_id 2 custom pid2 (this is because the pets owner is user_id 1)
Here is where I am with my attempt at the moment:
SELECT users.*, transactions.*
FROM users
LEFT JOIN transactions on users.id = transactions.custom
This is where I'm falling over:
SELECT users.*, transactions.*
FROM users
LEFT JOIN pets ON pets.user_id = user.id
LEFT JOIN transactions on (users.id = transactions.custom
OR pets.pet_id REGEXP '^pid(transactions.custom)')
If you can't change the table design and the prefix pid is fixed you could use
OR (
pets.pet_id = SUBSTR(transactions.custom, 3)
AND SUBSTR(transactions.custom, 1 FOR 3) = 'pid')
see documentation to SUBSTR and because MySQL automatically converts numbers to strings as necessary, and vice versa, see: http://dev.mysql.com/doc/refman/5.7/en/type-conversion.html
You HAVE to refactor Your DB. Current structure will guarantee of speed problems.
Table transactions should looks like
CREATE TABLE transactions
(
id Int NOT NULL, (id of transaction)
pet_id Int, (can be null)
user_id Int (can be null)
other columns here...
)
;

Selecting results from 2 tables based on the variables in 3th table

I have 2 tabes in my database:
users - userID(primary key), username, password
courses - id(primary key), name, text
subscriptions - id(primary key), curso_id, user_id
right in the subscription table I am writing the users UserID inside -> user_id with the id of the course for which he is subscribed curso_id so the results in the subscrption database are like
subscribtions table:
id user_id curso_id
1 12 1
2 5 1
3 12 2
4 6 7
this is the users table:
users table
userID username password
1 user1 passw1
2
3
4
and this is the courses table:
course table:
id course_name descriotion
1 course one text
2
3
My question is how to make a sql Query which first select the course by $row['id'] which indicates the id variable from the courses database, and after that based on the 3th table subscription to list all the users which are subscribed to this course number. ?
and second question is how to list number of the subscribed users for a course selected by
$row['id']
Here is some kind of the alghorytm logic that I have right now
SELECT * FROM users WHERE id=5.courses(select from the database 'courses') AND 5-> SELECT ALL FROM table subscriptions user_id equal to id from table users
Not sure if I understood what you try to achieve, but if you want a list that shows you every user in every course with the name of the course and ordered by course name, this should make the deal.
select t1.*, t2.*, t3.* from users as t1, courses as t2, subscriptions as t3 where t3.user_id = t1.userID and t3.curso_id = t2.id order by t2.id
Not the nicest way to do this and from a performance aspect I would recommend to put this in several statements as joins are usually slow.
okay I found the way and here is the mysql query:
FROM users
INNER JOIN subscriptions
ON users.userID = subscriptions.user_id
WHERE subscriptions.curso_id = $ids"

MySQL Left Join with multiple rows

I'm looking to join a 2 tables but the second table has a one to many relation. Can I omit the entire row if any of the lines have a certain value? Let me explain more.
User table
id name email
1 bob bob#test.com
2 foo foo#test.com
Music table
id userId
1 1
1 2
2 1
3 1
2 2
Say I don't want it to show the user if he has a relation to music table id 2. Also looking for distinct user.
If I try something like this it will still show both users.
SELECT * FROM users u LEFT JOIN music m ON u.id = m.userId WHERE m.id <> 3
I want it to check all the rows and if it has the id 3, it won't show. I hope I made sense. Thanks a lot.
Try using sub query like this:
SELECT * FROM users
WHERE id NOT IN (SELECT userId FROM music WHERE id=3)
This query means to select all users if their id is not related with music.id 3.