SQL Query multi reference to a table - sql

I have two tables Task and User
Task PRIMARY KEY
IdTask
TaskName
IdHandler FOREIGN KEY REFERENCES IdUser
IdCreator FOREIGN KEY REFERENCES IdUser
User
IdUser PRIMARY KEY
Name
How to query with IdHandler and IdCreator reference to IdUser
Expected Result: TaskName, Name(Handler), Name(Creator)
PS: I'm also do not know if I can put Foreign Keys like that, at least SQL Server let me do it.

SELECT TaskName, h.Name [HandlerName], c.Name [CreatorName]
FROM Task t
INNER JOIN User h ON t.IdHandler = h.IdUser
INNER JOIN User c ON t.IdCreator = c.IdUser

Please see below query.
Select
tt.TaskName,
userHandler.Name as 'UserHandler',
userCreator.Name as 'UserCreator'
from
TasKTable tt
left join
User userHandler on userHandler.IdUser = tt.IdHandler
left join
User userCreator on userCreator.IdCreator = tt.IdHandler
select all field from all table
Select
tt.*,
userHandler.*,
userCreator.*
from
TasKTable tt left join
User userHandler on userHandler.IdUser = tt.IdHandler left join
User userCreator on userCreator .IdCreator = tt.IdHandler
You may also check this SQL Tutorial for reference.

Here is an alternative query not using JOINs
select T.NAME_TASK
,(select U1.NAME from USERS U1 where U1.ID_USER = T.ID_HANDLER) as HANDLER
,(select U2.NAME from USERS U2 where U2.ID_USER = T.ID_CREATOR) as CREATOR
from TASKS T
Refer to this db<>fiddle

Related

SQL Server Select from table where primary key does not appear as foreign key in another table

I have 3 tables -
User UserID PK
SecurityGroup SecurityGroupID PK, SecurityGroupName
UserSecurityGroup UserSecurityGroupID, UserID FK, SecurityGroupID FK
I am trying to select the names of the security groups that a user is NOT a part of.
A user can be a member of more than one group.
i.e. I have three security groups: Admin, Moderator, Member
I pass through a UserID. Said user is assigned to the Admin and Moderator groups but is NOT part of the Member group. I'm trying to display "Member".
These are my attempts so far:
Attempt 1 -
select tblSecurityGroup.SecurityGroupName
from tblSecurityGroup
inner join tblUserSecurityGroup
on tblSecurityGroup.SecurityGroupID = tblUserSecurityGroup.SecurityGroupID
inner join tblUser
on tblUserSecurityGroup.UserID = tblUser.UserID
where tblUser.UserID = 1
and tblSecurityGroup.SecurityGroupID not in (tblUserSecurityGroup.SecurityGroupID);
Attempt 2 -
select tblSecurityGroup.SecurityGroupName
from tblSecurityGroup
inner join tblUserSecurityGroup
on tblSecurityGroup.SecurityGroupID = tblUserSecurityGroup.SecurityGroupID
inner join tblUser
on tblUserSecurityGroup.UserID = tblUser.UserID
where tblUser.UserID = 1
and not exists (select tblSecurityGroup.SecurityGroupID
from tblSecurityGroup
where tblUserSecurityGroup.SecurityGroupID = tblSecurityGroup.SecurityGroupID);
Guidance for a nooby student would be most appreciated.
Your question can be answered by a not exists query. Here is one method:
select sg.SecurityGroupName
from tblSecurityGroup sg
where not exists (select 1
from tblUserSecurityGroup usg
where sg.SecurityGroupID = usg.SecurityGroupID and
usg.UserID = 1
);
Note that tblUser is not needed because UserID is in tblUserSecurityGroup.

Selecting rows which do not exist for a specific user

I have 4 tables (Users,Config,Fields,AvailableFields)
User's relevant schema is
UserID uniqueidentifier NOT NULL PRIMARY_KEY
Config's relevant schema is
ConfigID uniqueidentifier NOT NULL PRIMARY KEY
UserID uniqueidentifier NOT NULL FOREIGN KEY (User.UserID)
Field's relevant schema is
FieldID uniqueidentifier NOT NULL PRIMARY KEY
AvailableFieldID uniqueidentifier NOT NULL FOREIGN KEY (AvailableFields.AvailableFieldsID)
ConfigID uniqueidentifier NOT NULL FOREIGN KEY (Config.ConfigID)
AvailableFields relevant schema is
AvailableFieldID uniqueidentifier NOT NULL PRIMARY KEY
I am trying to return all of the Available fields for a specific user which they do not have in their Fields table.
Is there a way to do this with a join?
I cannot see a way as the only link between the template AvailableFields table is AvailableFieldID which is a foreign key inside Fields table.
Yes, use the INNER JOIN function with the Config as the first table and Field as the second table to get all users with a Config entry. Then use RIGHT JOIN to select all the available field entries and leave out users with no available field entry.
Then all of the select with WHERE AvailableFields.AvailableFieldID IS NULL. This joins the table with all results from Field/Config table. Then it selects the users who do not have an AvailableFields entry.
Code:
SELECT *
FROM Config
INNER JOIN Field ON Config.ConfigID = Field.ConfigID
RIGHT JOIN AvailableFields ON AvailableFields.AvailableFieldID = Field.AvailableFieldID
WHERE Field.UserID IS NULL
This will return all entries in AvailableFields that don't have a corresponding Field entry (i.e. No users) .
You need to use combination of INNER JOIN and RIGHT JOIN
SELECT af.AvailableFieldID
from Config C
inner join Field F on F.configid = c.configid
right join AvailableFields af on F.AvailableFieldID = af.AvailableFieldID
where f.AvailableFieldID is null
Use
SELECT AvailableFieldID FROM AvailableFields
WHERE AvailableFieldID NOT IN (
SELECT AvailableFieldID from Field f INNER JOIN Config c ON f.ConfigID = c.ConfigID INNER JOIN UserID u on u.UserID = c.UserID
WHERE UserID = "Your condition")
I hope resolve your problem.
I think the most intuitive way would be to use NOT IN with a subquery:
SELECT * from AvailableField
WHERE AvailableField.AvailableFieldId NOT IN
(SELECT AvailableFieldId FROM Field
INNER JOIN Config ON Config.ConfigId = Field.ConfigId
WHERE Config.UserId = ?)
Where ? is a placeholder for the ID of the user you are interested in.
If you are performance-sensitive and are using large tables, multiple joins would be better than this subquery approach.
The simplified version answering your question's requirements:
select af.AvailableFieldID
from AvailableFields af -- all available fields
left join (select distinct f.AvailableFieldID
from Config c
join Fields f
on c.ConfigID = f.ConfigID
where c.UserID = #UserID) AS UserHas -- the fields the user has
on af.AvailableFieldID = UserHas.AvailableFieldID
where UserHas.AvailableFieldID is null -- a field match for the user isn't there
This will also return AvailableFieldID that are not in a Config.
The version you probably want b/c it can be multi-users:
select u.UserID, af.AvailableFieldID
from Users u -- all users
cross join AvailableFields af -- all fields
left join (select distinct f.AvailableFieldID, c.UserID
from Config c
join Fields f
on c.ConfigID = f.ConfigID) AS UserHas -- the fields each user has
on u.UserID = UserHas.UserID
and af.AvailableFieldID = UserHas.AvailableFieldID
where UserHas.AvailableFieldID is null -- a field match for the user isn't there
and (#UserID is null or u.UserID = #UserID) -- option to limit it to one user

SQL Query With Join for 2 Tables

I'm unable to form a query with the following tables, which will find out all the Notes from Note table, which is created by any user, who belongs to the logged in user's same company.
Note:
note_id (int),
note_text (varchar),
created_by (int)
User:
user_id (int),
company_id (int)
Logged in user's user id is passed as parameter to the query.
I want to pick up notes from the table Notes where created_by in (user_id of all users whose company_id = company_id of LOGGED_IN_USER)
Please help me to formulate out the query. Looks pretty straight forward, but just can't reach to it's end.
I'm not sure if LOGGED_IN_USER is a table or another object, but if it is a table with the columns you referenced, a join like this would work.
select note_text
from Note n
JOIN User u ON u.user_id = n.created_by
JOIN LOGGED_IN_USER lin ON lin.user_id = u.user_id
and lin.company_id = u.company_id
u might need a Foreign Key for user_id to Notes. and use INNER JOIN
Thanks Vinnie and all for your responses. I finally succeeded to figure out the query. LOGGED_IN_USER_ID is just a numeric parameter which should be passed to the query.
select n.* from Note n where
n.created_by in (
select u1.user_id from User u1 inner join User u2
on u1.company_id=u2.company_id and u2.user_id = :LOGGED_IN_USER_ID*
)
Thanks again.
If i am not misunderstood your question,Try this way
SELECT note_text
FROM Note n
INNER JOIN User u ON u.user_id = n.created_by
WHERE n.created_by= (select u.user_id from User where company_id=LOGGED_IN_USER LIMIT 1 )

Select user details from a self relationship table

I have 3 tables (user, relationship and user_type) with these data (the relevant ones):
USER TABLE:
id, username, avatar, user_type_id
RELATIONSHIP TABLE:
id, user_id1, user_id2, relationship_points
USER_TYPE
id
I'm trying to create a single entry per relationship so, user with id "1" could be in user_id1 OR user_id2 in a relationship, so, I don't have to duplicate unnecessary data.
I already created (thanks to another StackOverflow answer) a query to select all relationship details from an user, but only if it's id is in "user_id1".
SELECT
r.id AS relationship_id,
r.relationship_points AS points,
u.username AS username,
u.avatar_url AS avatar
FROM
relationship AS r
INNER JOIN
user AS u
ON
r.user_id2 = u.id
INNER JOIN
user_type AS t
ON
u.user_type_id = t.id
WHERE
r.user_id1 = ?
But, as you can see, if the user is in "user_id2", it doesn't work.
I know I could make another query, but I think it's the "easy, lazy" way, and I would love to learn how to do this in a single query.
Let me know if this makes the trick:
SELECT
r.id AS relationship_id,
r.relationship_points AS points,
u.username AS username,
u.avatar_url AS avatar
FROM relationship AS r
INNER JOIN user u
ON r.user_id2 = u.id OR r.user_id1 = u.id
INNER JOIN user_type AS t
ON u.user_type_id = t.id
WHERE u.id = ?

Select statement using primary key with no primary key

Ok so I have a table for notes in my database and a table for users in my database. Lets say notes table looks like this:
NoteId NoteTitle NoteAuth
--------------------------------
1 TempTitle 254
2 TempTitle2 871
and Users table looks like:
UserId UserName
-------------------
254 Bob
871 Jim
How can I select from the Note table but select the NoteAuth as the UserName from the Users table. Basically how can I use a primary key without a primary key being set up on the table.
SELECT NoteID, NoteTitle, UserName
FROM Notes INNER JOIN Users ON Notes.NoteAuth = Users.UserID
There's no requirement for any keys to exist to use a column in a JOIN.
You can try something like this
SELECT Notes.NoteId, Notes.NoteTitle, Notes.NoteAuth
FROM Notes
INNER JOIN Users ON Notes.NoteAuth = Users.UserId
WHERE Users.UserName = 'Bob'
Edit
Here is a version that returns the user name for a specified note author.
SELECT Users.UserName, Notes.NoteId, Notes.NoteTitle, Notes.NoteAuth
FROM Notes
INNER JOIN Users ON Notes.NoteAuth = Users.UserId
WHERE Notes.NoteAuth = 254
select n.NoteId, n.NoteTitle, n.NoteAuth, u.UserName
from Notes n
inner join User u on n.NoteAuth = u.UserID
The lack of a primary key will cause lack of table integrity. Now you won't be able to create a foreign key between the tables. This means that going forward you will be allowed to create a note with a user that doesn't exist in the Users table.
This won't stop you from
SELECT n.NoteTitle, u.UserName
FROM NoteTable n LEFT JOIN Users u ON n.NoteAuth = u.UserId
That will work in SqlServer.
The problem is is if you have a note that has a NoteAuth that doesn't exist in the users table, you'll end up with a NULL username. Use an ISNULL to replace NULL with something like 'No Username'.
But like I said, there won't be any integrity between the tables.
SELECT U.Username, N.NoteTitle from Notes N, Users U WHERE N.NoteAuth = U.UserId