This is my table following now i want to find the list of follower of user 1 that are also followed by user 1
id | user | follower
-----------------------
1 | 1 | 2
2 | 2 | 1
3 | 1 | 3
4 | 3 | 1
For example i want to find the list of my followers who are also following me
With EXISTS:
select t.follower from tablename t
where
t.user = 1
and exists (
select 1 from tablename
where user = t.follower and follower = t.user
)
See the demo.
Results
| follower |
| -------- |
| 2 |
| 3 |
You could self-join the table:
SELECT f1.user
FROM followers f1
JOIN followers f2 ON f1.user = f2.follower AND f1.follower = f2.user
WHERE f1.follower = 1 -- For a specific user
Related
I'm trying write a query:
SELECT id FROM users WHERE status = 3
But if this sample returns an empty response, then I need instead to select the id where status = 4, and if it returns empty again, where status = 5.
How can I write a single query to solve this?
I think you simply want:
SELECT id
FROM users
WHERE status >= 3
ORDER BY status asc
LIMIT 1;
If you want multiple users:
SELECT u.id
FROM users u
WHERE u.status = (SELECT MIN(u2.status)
FROM users u2
WHERE u2.status >= 3
);
If you have a fixed list you want to test, you can also use:
select u.id
from users u
where u.status = 3
union all
select u.id
from users u
where u.status = 4 and
not exists (select 1 from users u2 where u2.status in (3))
union all
select u.id
from users u
where u.status = 5 and
not exists (select 1 from users u2 where u2.status in (3, 4));
You can use OR condition or use IN operator
SELECT id FROM users WHERE status = 3 or status = 3 or status = 5
or
SELECT id FROM users WHERE status IN (3,4,5)
I will use the case statement in the where clause:
select id
from users
where status = case when status = 3 and id is null then 4
when status = 4 and id is null then 5
else 3
end
Let me know if you have any question.
Assuming that your table look like this:
+----+--------+
| id | status |
+----+--------+
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
| 3 | 3 |
| 3 | 4 |
| 4 | 4 |
| 4 | 5 |
| 5 | 5 |
+----+--------+
And based on your condition where you want to see the lowest status first for each id, you can use MIN() operator.
So, from your original query:
SELECT id,MIN(status) FROM users GROUP BY id;
Then you'll get a result like this:
+----+-------------+
| id | MIN(status) |
+----+-------------+
| 1 | 3 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+-------------+
I have table user_answers :
id | quiz_id | user_id | question_id | choosen_answer_id |
1 | 1 | 2 | 1 | 5 |
2 | 1 | 2 | 2 | 6 |
3 | 1 | 2 | 3 | 7 |
4 | 1 | 3 | 1 | 5 |
5 | 1 | 3 | 2 | 8 |
6 | 1 | 3 | 3 | 9 |
I want to cont how many correct answers (same choosen_answer_id for same question_id ) has user with user_id = 3 compared with user_id = 2 on same quiz_id
In this example I should receive 1 because user with user_id = 3 answered correct only on question with question_id=1 (for user_id = 2, question_id = 1 choosen_answer_id = 5 and for user_id = 3, question_id = 1 choosen_answer_id = 5`).
Thanks
I understand that you are willing to count for how many questions both users have given the same answer. You could self-join the table as follows :
SELECT COUNT(*) AS number_of_identical_answers
FROM user_answers ua2
INNER JOIN user_answers ua3
ON ua3.user_id = 3
AND ua3.quiz_id = ua2.quiz_id
AND ua3.question_id = ua2.question_id
AND ua3.choosen_answer_id = ua2.choosen_answer_id
WHERE ua2.user_id = 2
If you want to display the joined records instead of counting them, you can change COUNT(*) to a list of columns from tables ua2 (answers of user 2) and ua3 (answers of user 3).
select user_id, count(*)
from table1 t1
join (select *from table1 where user_id = 2) t2
on t2.question_id = t1.question_id
where t2.choosen_answer_id = t1.choosen_answer_id
group by t1.user_id
I have a table Follow, which only holds records of which UserID follows which TargetID.
If asked for user A:
If neither A or B are following eachother, they have status of 0 for unrelated, and aren't included in the results.
If user A is following B but not vice versa, B has status 1 for
being followed.
If user B is following A but not vice versa, B has
status 2 for being a follower.
If A is following B, and B following
A, B has status of 3 for being a friend.
How can I, in a single MySQL query, get the relationship status for a given user and all its relationships above status 0?
Example:
Users:
+----+-------+
| id | Name |
+----+-------+
| 1 | Bob |
| 2 | Steve |
| 3 | Scott |
| 4 | Mary |
+----+-------+
Follow:
+----+--------+----------+
| id | UserID | TargetID |
+----+--------+----------+
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 3 | 2 | 1 |
| 4 | 4 | 1 |
+----+--------+----------+
Expected result for user 1:
+----------+--------+-------+
| TargetID | Status | Name |
+----------+--------+-------+
| 2 | 3 | Steve | (friend)
| 3 | 1 | Scott | (following)
| 4 | 2 | Mary | (follower)
+----------+--------+-------+
You can use subqueries as illustrated below:
-- FOR USER 1
SELECT A.id TargetID,
SUM(IFNULL((SELECT 1 C FROM Follow B WHERE B.UserID=1 AND B.TargetID=A.id),0) +
IFNULL((SELECT 2 C FROM Follow D WHERE A.id=D.UserID AND D.TargetID=1), 0)) Status
, A.name
FROM (SELECT * FROM Users WHERE ID<>1) A
GROUP BY A.id, A.Name
HAVING Status>0; -- for a compact result
-- NOW GLOBALLY
SELECT A.UserID, A.id TargetID,
SUM(IFNULL((SELECT 1 C FROM Follow B WHERE B.UserID=A.UserID AND B.TargetID=A.id),0) +
IFNULL((SELECT 2 C FROM Follow D WHERE A.id=D.UserID AND D.TargetID=A.UserID), 0)) Status
, A.name
FROM (SELECT E.id UserID, F.* FROM Users E JOIN Users F ON E.id<>F.id) A
GROUP BY A.UserID, A.id, A.Name
HAVING Status>0 -- for a compact result
ORDER BY A.UserID;
See DEMO on SQL Fiddle
I have not tried this but try something among the lines of:
Select t.targetid as TargetId,
IF (
(select count(id) from follow where
follow.Userid = f.target.id and follow.target_id = u.id) > 1,
-- mean’s the target is following user 1
(IF (
(select count(id) from follow where
follow.Userid = u.id and follow.target_id = f.targetid) > 1, 3, 2))
-- if user1 is following aswell, then its a friend, else its a follower
, 1)
-- else means its a following
as status,
u.name as Name from follow f
inner Join users u on u.id = f.targetid
where u.id = 1
Inner join to select user 1's relations (if it doesn't exist, they aren't related)
If there is a record, means they are one of 3:
This question is regarding this one: Joining multiple tables to get NOT EQUAL values in MySQL
I want to extend the following query:
SELECT
d.dataid,
d.colors,
u.userid,
u.username
FROM
users u
CROSS JOIN
datas d
WHERE
(u.userid , d.dataid) NOT IN (SELECT
c.userid, c.dataid
FROM
collections c)
AND u.userid = 1
For this data sample:
table datas table users table collections
dataid | colors | addedby userid | username collectionid | userid | dataid
-------------------------- ------------------- ------------------------------
1 | blue | 1 1 | Brian 1 | 1 | 1
2 | red | 1 2 | Jason 2 | 2 | 3
3 | green | 2 3 | Marie 3 | 1 | 3
4 | yellow | 3 4 | 3 | 2
These results are expected:
for Brian
dataid | colors | userid | username
-----------------------------------
2 | red | 1 | Brian
4 | yellow | 1 | Marie
for Jason
dataid | colors | userid | username
-----------------------------------
1 | blue | 2 | Brian
2 | red | 2 | Brian
4 | yellow | 2 | Marie
The row "addedby", which inherits the userid from users, has been added.
At the moment my query replaces the userid from users instead of the addedby from datas with the username.
I really need the userid from datas replaced, not the userid from users. :-)
Does anyone have a clue how to solve this?
Thanks in advance!
cheers
Just join users table once again with datas table. And in the output use username from this join.
SELECT
d.dataid,
d.colors,
uo.userid,
uo.username
FROM
users u
CROSS JOIN
datas d
INNER JOIN
users uo
ON d.added_by = uo.id
WHERE
(u.userid , d.dataid) NOT IN (SELECT
c.userid, c.dataid
FROM
collections c)
AND u.userid = 1
And I believe, that you might even write your query in this way
SELECT u.userid, u.username, d.dataid, d.colors
FROM username u
INNER JOIN datas d
ON u.userid = d.addedby
WHERE d.dataid NOT IN (
SELECT dataid
FROM collections
WHERE userid = 1
)
I have the follow structure
user
id | name
----------
1 | Foo
2 | Bar
profile
id | name | user_id
--------------------------
1 | Profile 1 | 1
2 | Profile 2 | 2
profile_access
id | user_id | profile_id
--------------------------
1 | 2 | 1
Expect the follow result from a query
id | name | user_id
-----------------------------------
1 | Profile 1 | 1
2 | Profile 2 | 2
1 | Profile 1 | 2
But I do't know how to "merge" these tables. I tried:
SELECT profile.*
FROM profile profile
LEFT JOIN profile_access AS profile_access
ON (
profile_access.profile_id = profile.id
)
Which returns
id | name | user_id
-----------------------------------
1 | Profile 1 | 1
2 | Profile 2 | 2
And
SELECT profile.*
FROM profile profile
RIGHT JOIN profile_access AS profile_access
ON (
profile_access.profile_id = profile.id
)
Which results
id | name | user_id
-----------------------------------
2 | Profile 1 | 2
What is the correct way to do this query? Am I using joins wrong or expecting a impossible result with these tables?
EDIT:
Expected result should be:
id | name | user_id
-----------------------------------
1 | Profile 1 | 1
2 | Profile 2 | 2
1 | Profile 1 | 2
It is unclear what the exact logic you want is, but the following returns the results in the question:
select p.id, p.name, p.user_id
from profile p
union all
select p.id, p.name, pa.user_id
from profile p join
profile_access pa
on pa.profile_id = p.id;
EDIT:
This returns:
id | name | user_id
-----------------------------------
1 | Profile 1 | 1
2 | Profile 2 | 2
1 | Profile 1 | 2
Note that the last row has a 1 for the id instead of a 2 (as in the original expected answer). This is sensible to me, because id = 1 is only tied to profile name = 'Profile 1' in the table. But, to get the actual output:
select p.id, p.name, p.user_id
from profile p
union all
select pa.profile_id, p.name, pa.user_id
from profile p join
profile_access pa
on pa.user_id = p.user_id;
The reason I went with the first solution is because the sample queries all join profile and profile_access on the profile_id field and not on the user_id field.