Sql Query - stuck with simple left join - sql

I've been stuck with this simple Sql query for last 3 hours and my mind is drawing blank.
I have a User table that captures name user_id etc
Then I have a friends table that captures who is friend of whom and their status
User
user_id
name
Friend
friend_id
user_id
user_friend_id
status (accepeted,pending etc)
What I want to do is - when a logged in user searches for a name say "John" - display a list of all johns on the website and next to each John - do a lookup with a friends table to see if the record exists - ie if the logged in User is a friend of any of the Johns
if it exists show the current status
if it does not exist then show "Add Friend"
So should I first run a query on User table like select user_id from User where name Like 'John%' and then use those Id's and run them against Friends table.
I am not able to get it.
Thanks

You start with all users that match your criterium (I'm not sure about the exact MySQL syntax):
SELECT u.user_id
FROM User u
WHERE u.name LIKE '%John%'
This gives you all target users. Next you want an outer join on the Friend table where you restrict the results to the currently logged in user:
SELECT u.user_id, f.status
FROM user u
LEFT OUTER JOIN Friend f ON f.friend_id = u.user_id
WHERE f.user_id = <currentUserId> AND u.name LIKE '%John%'
What you get is a result set that has the user ids of all users named John and a status flag that is either null or an actual status. If it is null, you have a potential new friend, if not, you have an existing friend.

Something like this might get you started.
COALESCE
SQL Statement
SELECT u.name, COALESCE(f.Status, 'Add Friend')
FROM User u
LEFT OUTER JOIN Friend f ON f.User_ID = u.User_ID
WHERE u.name = 'John'

Following query must solve your problem
select a.user_name,case when a.user_name like 'John%' then b.status else 'Add Friend' end case from users_det a,friend b where a.user_id = b.user_id

Related

SQL - query for searching data in both table at the same time?

Suppose I have a table called UserFollows, where I keep Follow relationships ;
UserId
FollowedId
Then I have a general Users table and it is like ;
Id
Username
I use a query like the following when I want to get all followers of a user with ID 100 ;
SELECT*FROM UserFollows WHERE FollowedId = 100;
And suppose that I also want to query the following case ;
I want to search among the followers of a particular user, with a specific Username.
So, It should be like GET ME ALL OF THE USERS THAT HAS THE WORD 'hey' IN THEIR USERNAMES AMONG THOSE FOLLOWING ME
If I had Username in my UserFollows table , I'd easily write it like ;
SELECT*FROM UserFollows WHERE FollowedId = 100 AND Username LIKE '%a';
But I don't keep their Usernames in UserFollows
You need to include the Users table in the query.
SELECT uf.*
FROM UserFollows uf
inner join Users u on u.Id = uf.UserId
WHERE uf.FollowedId = 100
AND u.Username LIKE '%a';
or, more clearly
SELECT uf.*
FROM UserFollows uf
inner join Users follower on follower.Id = uf.UserId
inner join Users followed on followed.Id = uf.FollowedId
WHERE followed.UserName = 'ME'
AND follower.Username LIKE '%a';
Although "followed" may be a keyword, so you would need different aliases or you would need to handle the names appropriately.

How can I find the businesses reviewed by users with 100 or more fans?

This is from a Coursera course I am working on. This question is not necessary to complete the assignment, it is something extra I was working on to enhance my own skills. The ER diagram is:
I want to see how the type of user that reviews a business effects whether or not it is open. The "review" table is connected to the "business" table and the "user" table. I want to see if a business has reviews from users that have 100 or more fans. This is the query I came up with:
SELECT
b.name AS [Business]
,COUNT(r.id) AS [Num Reviews]
,b.is_open [Is Open]
FROM review r
INNER JOIN business b ON r.business_id = b.id
INNER JOIN user u ON r.user_id = u.id
WHERE r.user_id IN (SELECT
u.id
FROM user u
WHERE fans > 100
)
But it returns an empty table. I think the issue might be in the last line where maybe it's looking to see if the user_id's for all of the reviews for a business are in the list instead of checking to see if just one is. Any help would be appreciated, it seems like a pretty complex query and I am new to SQL.
The review table links a business with a user.
Each entry in the review tables, says that user has reviwed a business.
You got fans in the user table, so looks like you need to filter only those users who have a fans >100 so just add it to the where clause
SELECT b.name AS [Business]
,r.id
,b.is_open [Is Open]
FROM review r
JOIN business b
ON r.business_id = b.id
JOIN user u
ON r.user_id = u.id
WHERE r.fans > 100
The number of fans are in the User table. Business_id and User_id are foreign keys in the Review table which makes it easy to access both the User table and the Business table.
select business.business_id, review.r_id, business.b_is_open
from business,review, user
where business.business_id = review.business_id and review.user_id = user.user_id and user.fans>100

PSQL query with join query from a db newbie

I have two database tables. I'll simplify for the sake of this question
USERS
id : int
email: varchar
EVENTS:
user_id: int
event_name: varchar
I'd like to build a query that'll give me an output like:
ID Email Event name
------- --------- ----------------------
1 r#r.com Test event 1
2 d#d.com Test event 2
Obviously the query will select * from EVENTS but will also need to match the user_id in EVENTS via join I assume, to be able to select the e-mail in the USERS table corresponding to the id.
Any ideas how the syntax would look like?
Try this
SELECT
u.id AS ID,
u.email AS Email,
e.event_name AS Event
FROM
users u JOIN events e ON u.id = e.event_id
SQL is best understood with potatoes: http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/

Query to add a column depending of outcome of there columns

I have a user table 'users' that has fields like:
id
first_name
last_name
...
and have another table that determines relationships:
user_id
friend_id
user_accepted
friend_accepted
....
I would like to generate a query that selects all the users but also add another field/column say 'network_status' that depends on the values of user_accepted and fiend_accepted. For example, if user_accepted is true friend_accepted is false I want the 'network_status' field to say 'request sent'. Can I possibly do this in one query? (I would prefer not to user if/else inside the query but if that's the only way so be it)
You will have to take a look at CASE Statement
Something like
SELECT u.id,
u.first_name,
u.last_name,
CASE
WHEN r.user_accepted = 1 AND r.friend_accepted = 0
THEN 'request sent'
ELSE 'Not sure'
END
FROM users u LEFT JOIN
relationships r ON u.id = r.user_id

Get the inverse of a join?

I am using SQL Server 2005. I have three tables - Users, Groups, and GroupUsers. GroupUsers contains the two PKs for a many-to-many relationship.
I have a view to get all the user information for a group as follows:
SELECT * FROM GroupUsers JOIN Users ON GroupUsers.UserID = Users.UserId
I want to create the inverse of this view - I want a list of all of the users NOT attached to a specific group. The following query would accomplish this:
SELECT * FROM Users WHERE UserID NOT IN
(SELECT UserID FROM GroupUsers WHERE GroupID=#GroupID)
However I don't want to have to specify the group, I want to know how to turn this into a view that joins the GroupID and then the UsersID and all the user info, but only for non-attached users.
I'm not sure how to do this, maybe something with the EXCEPT operator?
UPDATE:
I think this is my solution, unless someone comes up with something better:
SELECT
G.GroupId,
U.*
FROM
Groups G
CROSS JOIN
Users U
WHERE
U.UserId NOT IN
(
SELECT
UserId
FROM
GroupUsers
WHERE
GroupId=G.GroupId
)
You can use a left outer join to grab all of the users, then, blow away any user where there's a group attached. The following query will give you just the list of users where there's no group to be had:
select
u.*
from
users u
left outer join groupusers g on
u.userid = g.userid
where
g.userid is null
If you want to find all users not in a particular group:
select
u.*
from
users u
left outer join groupusers g on
u.userid = g.userid
and g.groupid = #GroupID
where
g.userid is null
This will only exclude the users in that particular group. Every other user will be returned. This is because the groupid condition was done in the join clause, which limits the rows joined, not returned, which is what the where clause does.
If I understand it correctly, you will have to do a cartersian result of users & groups and reduce the result derived from GroupUsers.
That will give you records of users which do not have any groups attached to it.
I apologize if I didn't understand the question correctly.
EDIT: Cartesian result will give you users * groups. You will have to subtract GroupUsers from it. I am sorry, I do not have SQL ready for it & can't try it out at this point.
I couldn't figure out how to get previous version to work via active record, got some of the way there but had to write an SQL in statement. I believe this also accomplishes the same thing.
SELECT * FROM Users WHERE UserID NOT IN
(SELECT U.UserID FROM GroupUsers AS G, Users as U WHERE G.UserID <> U.UserID)
Couldn't test however this query in rails worked just fine:
# Gets Pre-Clients. Has client information but no project attached
Contact.joins(:client).includes(:projects => :primary_contact).
where("contacts.id NOT IN (select contacts.id from contacts,
projects where projects.primary_contact_id = contacts.id)")
Thanks for the post got me 90% of the way there.