I need to use mysql to show users (A) that not follow B, but they (A) are followed by B. This is gonna be used to suggest connections on a social media website.
My table structure:
ID
FOLLOWED
FOLLOWER
I've tried to use
LEFT JOIN
or
NOT EXISTS, but didn't work.
#DRapp shows me how to user LEFT JOIN on this query. That works. Now, how to add the users information on this query (LEFT JOIN + INNER JOIN).
Inner join need to be with follow table and user table (INNER JOIN users ON follow.follower = user.id)
Users`s table structure:
ID
Name
Given the scenario of sample data of "YourTable"
ID Follower Followed
1 A C
2 B C
3 B D
4 B E
5 C B
6 D A
The people followed by "B" include "C", "D" and "E" users.
From that, only user "C" follows "B". So, what you are looking for is any where no MATCH for A/B, B/A type of combination. So that is the basis of the LEFT-JOIN. The WHERE clause is only querying those records based on the user "B" you are considering as the originating "follower".
select
yt.Followed,
u.name
from
YourTable yt
left join YourTable yt2
on yt.Followed = yt2.Follower
AND yt.Follower = yt2.Followed
JOIN Users u
on yt.Followed = u.id
where
yt.Follower = 'B'
AND yt2.Followed IS NULL
To get then name, notice the join is to your ORIGINAL table that was based on user "B", but NOT finding the corrresponding inverse match. So, we are joining on the ORIGINAL record's Followed (who "B" is following) to the user table by the same ID in the user table. Then grab the user's name to the query.
Related
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
;
Table: user
id
compId
1
comp1
2
comp1
Table: Company
id
name
comp1
coke
comp2
pepsi
need a MYSQL query which should fetch company record only if it has one or more users, when passed a company id. I will have other where conditions on company table.
Can this be achieved by joins?
example 1: query(comp1) result: coke (atleast one user exists)
example 2: query(comp2) result: no records (Since no user exists who belong to company comp2)
What you're asking for is called a semi-join. This returns one row from company if there are one or more matching rows in user.
If you use a regular join:
SELECT c.* FROM company c JOIN user u ON u.compid = c.id;
This does return the row from company, but you might not like that it returns one row per user. I.e. rows in the result are multiplied by the number of matches.
There are several possible fixes for this, to reduce the results to one row per company.
SELECT DISTINCT c.* FROM company c JOIN user u ON u.compid = c.id;
SELECT c.* FROM company c JOIN (SELECT DISTINCT compid FROM user) u ON u.compid = c.id;
SELECT * FROM company c WHERE c.id IN (SELECT compid FROM user);
SELECT * FROM company c WHERE EXISTS (SELECT * FROM user WHERE compid = c.id);
Which one is best for your app depends on many factors, such as the sizes of the tables, the other conditions in the query, etc... I'll leave it to you to evaluate them given your specific needs.
I have 3 tables :
Person table stores basic person wise details with ID as primary Key
This person can have relationships (father / mother etc), which are saved in Relationship table, however the users for them are created in Person table (e.g. ID = 2,3 in person table), This way we know that 2,3 are related to user 1 (carry).
We also have 3rd table - address, which store user ID wise addresses.(for both a user and his related persons, who are also users)
I want to find out if an address exists for either a user or for his related users in SQL. How to achieve this ?
You can combine two rules and search on the combined table as below
SELECT * FROM
(
SELECT username,id,Address.Address
FROM Person
INNER JOIN Address ON Person.id = Address.Userid
UNION ALL
SELECT username,id,Address.Address
FROM Person
INNER JOIN Relationship ON Relationship.Relatedid = Person.id
INNER JOIN Address ON Relationship.Userid = Address.Userid
) as RES
WHERE Address = 'xyz road'
Also you can find DBFiddle link to workout
Query:
select p.id,p.username,(case when a.userid is null then 'No' else 'Yes'end) IsAddressAvailable
from Person p
left join Address a on p.id=a.Userid
Output:
id
username
IsAddressAvailable
1
Carry
Yes
2
Carry-Father
No
3
Carry-Mother
Yes
db<fiddle here
The main table has 4 columns:
User Activity Table
userActivityId userId therapistId activityId
1 1 1 1
Each of these columns is a table and these values are all foreign keys.
Basically im trying to run a query that will join to the users table and pull their first and last name based off the user Id.Same thing with therapist - join to the therapist table, pull first + last name.And finally Join to the Activity table and pull the activity name and path from the activity Id
The other tables look like this:
User Table
userId fName lName
Therapist Table
therapistId therapistFirstName therapistLastName
Activity Table
activityId activityTitle activityPath
So far my query looks like
SELECT
User_Activities.userId,
User_Activities.therapistId,
User_Activities.activityId,
Activities.activityTitle,
Activities.activityPath,
Users.fName,
users.lName,
Therapists.therapistFirstName,
Therapists.therapistLastName
FROM
User_Activities
INNER JOIN Users
ON User_Activities.userId = Users.userId
INNER JOIN Therapists ON
User_Activities.therapistId = Therapists.therapistId
INNER JOIN Activities ON
Activities.activityId = User_Activities.userActivityId
WHERE
User_Activities.userId = 1;
When I run this query It only returns 1 row as a result. However there are two activities in the User_Activites table assigned to userId 1.
If I change : INNER JOIN Activities ON
Activities.activityId = User_Activities.userActivityId
from an INNER JOIN to the LEFT JOIN it will display the second row, however the activityTitle and activityPath will be displayed as NULL in the second row.
userActivityId userId therapistId activityId activityId activityTitle activityPath fName lName therapistFirstName therapistLastName
1 1 1 1 1 Brain GZZ0zpUQ S C M D
11 1 1 1 NULL NULL NULL S C M D
You have pretty much answered your question. The second activity does not have a valid ActivityId.
If you want all activities for a user, then you should phrase the query as:
SELECT . . .
FROM Users u LEFT JOIN
User_Activities ua
ON ua.userId = u.userId LEFT JOIN
Therapists t
ON ua.therapistId = t.therapistId LEFT JOIN
Activities a
ON a.activityId = ua.userActivityId
WHERE u.userId = 1;
You want to start with the table where you want to keep all the rows. Then use LEFT JOIN to bring in other tables.
Two other changes of note:
Table aliases are used to simplify reading and writing the query. The SELECT needs to change to use the aliases.
The WHERE clause refers to the Users table rather than UserActivities.
I am looking for a better way of retrieving data from my sql tables.
Table 1: User data
- User Id
- User Created date
Table 2: Mapping of the user with a role
- User Id
- Role
Table 3
Role definition
Table 4 (may or may not have user data based on his activities on the site)
User data
Eg.
- User Id
- Total counts of the number of visits made on the portal
I am looking to write least amount of queries(preferably 1) to do the following
*I want to print the top users for each of the role types who have highest total count *
The output would read something like the following:
Header UserId---Rolename--Total Count
Row1 Test1 ---Staff --1293
Row2 Test2 ---Faculty --1223
Row3 Test3 ---Dean --2283928
Any suggestions?
Is this what you're looking for:
SELECT a.UserId, b.Role, c.TotalCount
FROM TABLE1 as a join Table2 as b on a.UserId = b.UserId
join Table 4 as c on a.UserId = c.UserId
ORDER BY c.TotalCount DESC
LIMIT 3