Database join where - sql

Database
Users
id
lastname
firstname
1
Sardor
Sattarov
2
Nurmuhammad
To’xtayev
3
Jasur
Sattarov
Group_items
id
student_id
group_id
1
2
55
2
1
55
3
2
11
Return
example 1
condition
users.id == group_items.student_id do not publish a table that satisfies this desire group_items.id == 55
id
lastname
firstname
3
Jasur
Sattarov
example 2
condition
users.id == group_items.student_id do not publish a table that satisfies this desire group_items.id == 11
id
lastname
firstname
1
Sardor
Sattarov
3
Jasur
Sattarov

Looks like you want OR instead of AND.
SELECT
*
FROM
users u
LEFT JOIN group_items gi ON u.id = gi.student_id
WHERE
gi.student_id IS NULL
OR gi.group_id <> 5
Studends without a group plus studends in all groups but 5.

Please try this,
Example 1:
SELECT
U.ID,U.LASTNAME,U.FIRSTNAME
FROM
USERS U
LEFT JOIN
GROUP_ITEMS G
ON U.ID=G.STUDENT_ID
WHERE G.GROUP_ID <>55
Example 2:
SELECT
U.ID,U.LASTNAME,U.FIRSTNAME
FROM
USERS U
LEFT JOIN
GROUP_ITEMS G
ON U.ID=G.STUDENT_ID
WHERE G.GROUP_ID <>11

You can use join statements in SQL
For Example
for return 1:
SELECT * FROM users u left join group_items gi on gi.student_id = u.id
this query will return all students with their group_id
for filter by group you can use where statement.
SELECT * FROM users u left join group_items gi on gi.student_id = u.id where gi.group_id<>11

Related

How to sum up max values from another table with some filtering

I have 3 tables
User Table
id
Name
1
Mike
2
Sam
Score Table
id
UserId
CourseId
Score
1
1
1
5
2
1
1
10
3
1
2
5
Course Table
id
Name
1
Course 1
2
Course 2
What I'm trying to return is rows for each user to display user id and user name along with the sum of the maximum score per course for that user
In the example tables the output I'd like to see is
Result
User_Id
User_Name
Total_Score
1
Mike
15
2
Sam
0
The SQL I've tried so far is:
select TOP(3) u.Id as User_Id, u.UserName as User_Name, SUM(maxScores) as Total_Score
from Users as u,
(select MAX(s.Score) as maxScores
from Scores as s
inner join Courses as c
on s.CourseId = c.Id
group by s.UserId, c.Id
) x
group by u.Id, u.UserName
I want to use a having clause to link the Users to Scores after the group by in the sub query but I get a exception saying:
The multi-part identifier "u.Id" could not be bound
It works if I hard code a user id in the having clause I want to add but it needs to be dynamic and I'm stuck on how to do this
What would be the correct way to structure the query?
You were close, you just needed to return s.UserId from the sub-query and correctly join the sub-query to your Users table (I've joined in reverse order to you because to me its more logical to start with the base data and then join on more details as required). Taking note of the scope of aliases i.e. aliases inside your sub-query are not available in your outer query.
select u.Id as [User_Id], u.UserName as [User_Name]
, sum(maxScore) as Total_Score
from (
select s.UserId, max(s.Score) as maxScore
from Scores as s
inner join Courses as c on s.CourseId = c.Id
group by s.UserId, c.Id
) as x
inner join Users as u on u.Id = x.UserId
group by u.Id, u.UserName;

Dynamically select the table to join in Postgres with case statements

My notifications table has a column called action_id and trigger_type. I want to INNER JOIN action_id with another table (Like users or posts) depending on the trigger_type. I wrote the following query but it throws an error.
Table structure
users
display_name
username
id
John
Doe
1
Larry
Doe
2
posts
post_title
post_body
id
user_id
Hello
Hello world
1
2
comments
comment_text
post_id
id
user_id
Hello
1
1
1
notifications
read
trigger_id
id
target_id
action_id
trigger_type
false
1
1
2
1
0
false
1
2
2
1
1
trigger_type = 0 means its a like 1 means its a comment
SELECT notifications.*, users.display_name, users.username, users.profile_pic, posts.title
FROM notifications
INNER JOIN users ON users.id = notifications.trigger_id
(
CASE notifications.trigger_type
WHEN 0 THEN INNER JOIN users ON users.id = notifications.action_id
WHEN 1 THEN INNER JOIN posts ON posts.id = notifications.trigger_id
)
You cannot conditionally join like that. Instead, use left join like this:
SELECT n.*,
-- whatever columns you want from the trigger user go here
un.display_name, un.username, un.profile_pic, p.title
FROM notifications n JOIN
users u
ON u.id = n.trigger_id LEFT JOIN
users un
ON un.id = n.action_id AND n.trigger_type = 0 LEFT JOIN
posts p
ON p.id = n.action_id AND n.trigger_type = 1;

Retrieving data information from another table Left Join SQL

User A liked User C Post
Table Users:
id_user name
1 A
2 B
3 C
Table Posts:
id_post post user_post
15 hi 2
19 how are you 3
23 hello 2
Table likes:
id_like id_liker liked_post_id liked_user_id
45 1 19 3
From table likes I show results
User 1 liked post 19 that belongs to user 3
SELECT liked_user_id,_liker,liked_post_id
FROM likes
WHERE liked_user_id = 3
How do I show the next
User A liked User C Post which is "How are you"
I tried but I get an error:
SELECT name
FROM users as u
LEFT JOIN
(SELECT id_post, post, user_post
FROM posts as p
LEFT JOIN
(SELECT liked_user_id, id_liker, liked_post_id
FROM likes
WHERE liked_user_id = 3
) AS b ON u.id_post = b.liked_post_id
) AS c ON u.id_user = c.user_post
SELECT u.`name`, v.`name`, p.post
FROM likes
LEFT JOIN Users as u on likes.id_liker=u.id_user
LEFT JOIN Users as v on likes.liked_user_id=v.id_user
LEFT JOIN Posts as p on likes.liked_post_id=p.id_post
WHERE likes.liked_user_id=3
SELECT liker.name AS liker_name
,liked.name AS liked_name
,p.post
FROM likes AS l
LEFT JOIN Users AS liker ON liker.id_user = l.id_liker
LEFT JOIN Users AS liked ON liked.id_user = l.liked_user_id
LEFT JOIN Posts AS p ON p.id_post = l.liked_post_id
AND l.liked_user_id = p.user_post
WHERE l.liked_user_id = 3

SQL JOIN Returning no values

I am working with 3 tables with the following Names and columns:
*Table 1*
**Users**
UserID UserName UserTypeNumber
1 John 1N
2 Mary 1N
3 Doe 1N
4 Sullivan 2N
5 Sally 1N
**Key = UserID**
*Table 2*
**MobileUsers**
Userid MobileAccess
1 Yes
2 Yes
3 Yes
4 Yes
5 No
**Key = UserID**
*Table 3*
**PanCards**
UserID CARD_NUMBER
3 2222
4 3333
5 1111
Key = UserID
Explanation:
Every user is available in both Users and MobileUsers table
However, not all users are present in PanCards table. This is
because only users that have been assigned a Card appears in the
PanCards table. In this case Doe with UserID=3 and Sullivan with UserID=4 have a card, hence they appear in PanCards table
Problem:
What I want to achieve is to filter out the users from
MobileUsers table that have MobileAccess equivalent to Yes and thier UserTypeNumber equivalent to 1N in the Users table but are not present in the PanCards table.
What I have so far is the below SQL Query:
SELECT MobileUsers.Userid, MobileUsers.MobileAccess
FROM MobileUsers
INNER JOIN Users
ON MobileUsers.Userid = Users.UserID
INNER JOIN PanCards
ON Users.UserID = PanCards.UserID
WHERE MobileUsers.MobileAccess = 'Yes'
AND
Users.UserTypeID = '1N'
AND
MobileUsers.Userid NOT IN
(SELECT PanCards.UserID FROM PanCards)
Result is an Empty table
Userid MobileAccess
However what i want is to have the below result returned:
Userid MobileAccess
1 Yes
2 Yes
How do i fix this and get the correct results please ?
If you want to use JOIN, then use a LEFT JOIN for PanCards and check for no matches:
SELECT mu.*
FROM MobileUsers mu JOIN
Users u
ON mu.Userid = u.UserID LEFT JOIN
PanCards pc
ON pc.UserID = mu.UserID
WHERE mu.MobileAccess = 'Yes' AND
u.UserTypeID = '1N' AND
pc.UserID IS NULL;
I think your query would work without the join to PanCards.
WITH NotPan -- First get users that are not in the PanCards table
AS
(
select * from Users as u
where u.userid not in (select userid from PanCards)
)
-- Easy from here
select * from NotPan as n
inner join mobileUsers m on m.userid = n.userid
inner join Users as u on n.userid = u.userid
WHERE m.MobileAccess = 'Yes' and u.UserTypeNumber = '1N'

SQL Join to only one record in one to many relationship

I have the following query:
SELECT c.[ClientID]
,u.[AccessId]
FROM [tblClient] c
INNER JOIN [tblUser] u ON u.[Id] = c.[UserId]
This tblUser has multiple ID's for each UserID row.
So it would look like this:
UserID AccessID
1 AD2F0A-965B78414-2B34906F2-0127AA5A
1 ID2F0A9-65B784-142B34906-F20127AA5A
1 UD2F0A9-65B78-4142B34906F-20127AA5A
2 TD2F0A9-65B784142-B34906F-20127AA5A
2 RD2F0A9-65B784142B3-4906-F20127AA5A
3 WD2F0A96-5B784142-B34906F201-27AA5A
3 ZD2F0A96-5B784-142B34-906F2-0127AA5A
3 CD2F0A965-B784142B3-4906F20-127AA5A
Is there a way to only get the top(or 1) AccessId for each UserID? It doesnt matter which AccessID i get, I just want 1 of them.
Thanks
SELECT c.[ClientID], MAX(u.[AccessId])
FROM [tblClient] c
INNER JOIN [tblUser] u
ON u.[Id] = c.[UserId]
GROUP BY c.[ClientID]