Query from 3 tables - sql

I have 3 tables: TblUsers, tblBridge, and tblAssignments.
The bridge contains the ID of the user and the corresponding AssignmentID for that user.
I'm trying to find the user with a certain assignment #Assignment, but also where tblUser.isAdmin = Yes.
I feel like its possible with Joins, I just can't find a good example on how to get it done.

I'm assuming this is in a stored procedure which receives an #assignment var.
select tu.[Users] from TblUsers tu
join tblBridge tb on tu.id=tb.TblUsersid
join tblAssignments ta on ta.id = tb.tblAssignmentsid
where ta.[Assignment] = #Assignment
and tu.[isAdmin] = 'Yes'

SELECT u.* FROM tblBridge b
JOIN tblUsers u ON u.ID = b.tblUsersID
JOIN tblAssignments a ON a.ID = b.tblAssignmentsID
WHERE u.isAdmin = 'yes' AND a.name = 'searched assignment'
It's MANY-TO-MANY Relation so you need select many-to-many table and join it to assigments and users also put in where condition for admin.
I'm not sure if the names are exact the same as you have in your DB so you need adjust it to yor needs.
I don't know the field that you look for in assigment table so change a.name to your needs.

Related

SQL Where on different table

SELECT * FROM student_mentor sm INNER JOIN users u
ON sm.student_id = u.user_id
WHERE sm.teacher_id = $teacher_id
Teacher_id being the session id,
I want to see all the students that have the same mentor.
Right now if I run this I just see all of the students twice, maybe one of you knows why?
My db scheme
You are not specifying on which columns you want to do the join, so you're getting a cross reference where all records are joined to all records.
You should do something like (not sure about your column names):
SELECT * FROM student_mentor sm INNER JOIN users u
ON sm.student_id = u.user_id
WHERE sm.teacher_id = $teacher_id

Is it true that JOINS can be used everywhere to replace Subqueries in SQL

I heard people saying that table joins can be used everywhere to replace sub-queries. I tested it in my query, but found that appropriate data set was only retrieved when I used sub-queries. I was not able to get same data set using joins. I am not sure if what I found is right because I am a newcomer in RDBMS, thus not so much experienced. I will try to draw the schema (in words) of the database in which I was experimenting:
The database has two tables:
Users (ID, Name, City) and Friendship (ID, Friend_ID)
Goal: Users table is designed to store simple user data and Friendship table represents Friendship between users. Friendship table has both the columns as foreign keys, referencing to Users.ID. Tables have many-to-many relationship between them.
Question: I have to retrieve Users.ID and Users.Name of all the Users, which are not friends with a particular user x, but are from same city (much like fb's friend suggestion system).
By using subquery, I am able to achieve this. Query looks like:
SELECT ID, NAME
FROM USERS AS U
WHERE U.ID NOT IN (SELECT FRIENDS_ID
FROM FRIENDSHIP,
USERS
WHERE USERS.ID = FRIENDSHIP.ID AND USERS.ID = x)
AND U.ID != x AND CITY LIKE '% A_CITY%';
Example entries:
Users
Id = 1 Name = Jon City = Mumbai
Id=2 Name=Doe City=Mumbai
Id=3 Name=Arun City=Mumbai
Id=4 Name=Prakash City=Delhi
Friendship
Id= 1 Friends_Id = 2
Id = 2 Friends_Id=1
Id = 2 Friends_Id = 3
Id = 3 Friends_Id = 2
Can I get the same data set in a single query by performing joins. How? Please let me know if my question is not clear. Thanks.
Note: I used inner join in the sub-query by specifying both tables: Friendship, Users. Omitting the Users table and using the U from outside, gives an error (But if not using alias for the table Users, query becomes syntactically okay but result from this query includes ID's and names of users, who have more than one friends, including the user having ID x. Interesting, but is not the topic of the question).
For not in you can use left join and check for is null:
select u.id, u.name
from Users u
left join Friends f on u.id = f.id and f.friend_id = #person
where u.city like '%city%' and f.friend_id is null and u.id <> #person;
There are some cases where you can't work out your way with just inner/left/right joins, but your case is not one of them.
Please check sql fiddle: http://sqlfiddle.com/#!9/1c5b1/14
Also about your note: What you tried to do can be achieved with lateral join or cross apply depending on the engine you are using.
You can rewrite your query using only joins. The trick is to join to the User tables once with an inner join to identify users within the same city and reference the Friendship table with a left join and a null check to identify non-friends.
SELECT
U1.ID,
U1.Name
FROM
USERS U1
INNER JOIN
USERS U2
ON
U1.CITY = U2.CITY
LEFT JOIN
FRIENDSHIP F
ON
U2.ID = F.ID AND
U1.ID = F.FRIEND_ID
WHERE
U2.id = X AND
U1.ID <> U2.id AND
F.id IS NULL
The above query doesn't handle the situation where USER x's primary key is in the FRIEND_ID column of the FRIENDSHIP table. I assume because your subquery version doesn't handle that situation, perhaps you create 2 rows for each friendship, or friendships are not bi-directional.
Joins and subqueries can be used to achieve similar results in some cases, but certainly not all. As an example, this query with a subquery could not be achieve vis-a-vis a join:
SELECT ID, COLUMN1, COUNT(*) FROM MYTABLE
WHERE ID IN (
SELECT DISTINCT ID FROM MYTABLE
WHERE COLUMN2 NOT IN (VALUES1, VALUES2)
)
GROUP BY ID;
This is only one example, but there are many.
Conversely, you cannot get information from another table by using a subquery without joining it.
As to your example
SELECT ID, NAME FROM USERS AS U
WHERE U.ID NOT IN (
SELECT FRIENDS_ID FROM FRIENDSHIP, USERS
WHERE USERS.ID = FRIENDSHIP.ID AND USERS.ID = x)
AND U.ID != x AND CITY LIKE '% A_CITY%';
This could be constructed as:
select ID, NAME from users u
join FRIENDSHIP f on f.ID = u.ID
where u.ID = x
and u.ID != y
and CITY like '%A_CITY';
I changed your second x to a y assumptively, so it wouldn't cause confusion.
Of course, you may also want to LEFT JOIN aka LEFT OUTER JOIN if there is a chance that there may be multiple results in the FRIENDSHIP table.

Access SQL LEFT JOIN not returning results

I have three tables: Comments, Users and CommentsHelpfulness.
Users can submit several comments, which are stored in the Comments table.
CommentsHelpfulness has three columns: UserID, CommentID and a "Helpful" Boolean. Every user can indicate for every comment if they find it useful, which will create an entry in the CommentsHelpfulness table.
I want a query that gives me all Comment IDs, with the name of the user that submitted it and shows whether the currently logged in user found it helpful, did not find it helpful or did not say anything about it. So the ID of a comment the current user did not express his opinion about should still be output, just without the helpful Boolean.
To me that sounds like it should be done like this using a left join:
SELECT Comments.ID, Users.Nom, CommentsHelpfulness.Helpful
FROM (Comments INNER JOIN Users
ON Comments.UserID = Users.ID)
LEFT JOIN CommentsHelpfulness
ON (CommentsHelpfulness.CommentID = Comments.ID
AND (CommentsHelpfulness.UserID = ?))
Unfortunately this does not output Comment IDs without an entry in the CommentsHelpfulness table. Why does this not work? Is it because of Access?
I think the issue is the inner join, not the left join.
Try removing that table:
SELECT c.ID, ch.Helpful
FROM Comments as c LEFT JOIN
CommentsHelpfulness as ch
ON ch.CommentID = c.ID AND
ch.UserID = ?
select c.id, c.Nom, d.Helpful from (
select a.ID, b.Nom from Comments a left join Users b
on a.UserID = b.ID) c left join CommentsHelpfulness d
on d.CommentID = c.ID;

Selecting records in SQL based on another table's contents

I'm a bit new to SQL and have trouble constructing a select statement. I have two tables:
Table users
int id
varchar name
Table properties
int userID
int property
and I want all user records which have a certain property. Is there a way to get them in one SQL call or do I need to first get all userIDs from the properties table and then select each user individually?
Use a JOIN:
SELECT U.id, U.name, P.property FROM users U
INNER JOIN properties P ON P.userID = U.id
WHERE property = 3
If there's only one property row per user you want to select on, I think this is what you want:
select
users.*
from
users,
properties
where
users.id = properties.userID
and properties.property = (whatnot);
If you have multiple property rows matching "whatnot" and you only want one, depending your database system, you either want a left join or a distinct clause.
Check out the JOIN command. You could write a query like the following:
SELECT
name
FROM
users u
INNER JOIN properties p
ON u.id = p.userID
WHERE
p.property = <some value>
You're looking to JOIN tables.
Assuming the id and userID columns have the same meaning, it's like this:
select u.name
from users u inner join properties p
on u.id = p.userID
where p.property = :ValueToFind
SELECT [Name] FROM Users u
JOIN Properties p on p.UserID=u.ID
WHERE p.Property=1
Obviously it depends what flavour of RDBMS and TSQL you are using.

How to show some columns of 3 tables in SQL?

I have 3 tables: Prestam, Book, User.
Table Prestam
Id_Prestam
Date_Prest
Date_Dev
Id_Book 'link
Id_User 'link
Table Book
Id_Book
Title
Table User
Id_User
Name
Last Name
Here is my SQL code, although there is an error in the syntax, specifically in:
, Pr.Id_User = User.Id_User
SELECT
Pr.Id_Prestam, Pr.Date_Prest, Pr.Date_Dev,
Lbr.Title,
Usr.Name, Usr.Last Name
FROM
Prestam Pr, Book Lbr, User Usr
WHERE
Pr.Id_Book = Lbr.Id_Book, Pr.Id_User = Usr.Id_User
The goal is to show me the following:
Id_Prestam
Date_Prest
Date_Dev
Title
Name
Last Name
Is there any way to make this possible?
I had heard about creating views but, I do not know how to handle it
CREATE VIEW List AS
To resolve that particular syntax error, since you have given the User table the alias of Usr you need to change this:
, Pr.Id_User = User.Id_User
To this:
, Pr.Id_User = Usr.Id_User
Then you'll need to take a look at using the JOIN statement to join tables together. The WHERE statement doesn't allow you to join tables together.
There is a typo in your SQL code.
In this part of the query, you are referring to the User table alias :
, Pr.Id_User = User.Id_User
But that alias does not exist, it is called Usr instead.
Bottom line, you should be using JOINs instead of stuffing your relationships in the WHERE clause.
Here is a new query :
SELECT
Pr.Id_Prestam,
Pr.Date_Prest,
Pr.Date_Dev,
Lbr.Title,
Usr.Name,
Usr.Last Name
FROM Prestam Pr
INNER JOIN Book Lbr on Pr.Id_Book = Lbr.Id_Book
INNER JOIn User Usr on Pr.Id_User = Usr.Id_User
Looks like you can do some sort of join on the tables.
i.e.
select *
from Prestam P
inner join Book B on P.ID_Book = B.ID_Book
inner join User U on P.ID_User = U.ID_User
Join Prestam with the other 2 tables:
SELECT
Prestam.Id_Prestam, Prestam.Date_Prest, Prestam.Date_Dev,
Book.Title,
User.Name, User.`Last Name`
FROM
(Prestam INNER JOIN Book ON Prestam.Id_Book = Book.Id_Book)
INNER JOIN User
ON Prestam.Id_User = User.Id_User;
Solution --> change coma to AND
SELECT
Pr.Id_Prestam, Pr.Date_Prest, Pr.Date_Dev,
Lbr.Title,
Usr.Name, Usr.Last Name
FROM
Prestam Pr, Book Lbr, User Usr
WHERE
Pr.Id_Book = Lbr.Id_Book AND Pr.Id_User = Usr.Id_User