Access SQL LEFT JOIN not returning results - sql

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;

Related

SQL issue with RIGHT JOINS

The following SQL query does exactly what it should do, but I don't know how to change it so it does what I need it to do.
SELECT
a.id AS comment_id, a.parent_comment_id, a.user_id, a.pid, a.comment, a.blocked_at, a.blocked_by, a.created_at, a.updated_at,
b.name, b.is_moderator, COUNT(IF(d.type = 1, 1, NULL)) AS a_count, COUNT(IF(d.type = 2, 1, NULL)) AS b_count
FROM
comments AS a
RIGHT JOIN
users AS b ON b.id = a.user_id
RIGHT JOIN
node_user AS c ON c.user = b.id
RIGHT JOIN
nodes AS d ON d.id = c.node
WHERE
a.pid = 999
GROUP BY
comment_id
ORDER BY
a.created_at ASC
It gets all comments belonging to a specific pid, it then RIGHT JOINS additional user data like name and is_moderator, then RIGHT JOINS any (so called) nodes including additional data based on the user id and node id. As seen in the SELECT, I count the nodes based on their type.
This works great for users that have any nodes attached to their accounts. But users who don't have any, so whose id doesn't exist in the node_user and nodes tables, won't be shown in the query results.
So my question:
How can I make it so that even users who don't have any nodes, are still shown in the query results but with an a_count and b_count of 0 or NULL.
I'm pretty sure you want left joins not right joins. You also want to fix your table aliases so they are meaningful:
SELECT . . .
FROM comments c LEFT JOIN
users u
ON u.id = c.user_id LEFT JOIN
node_user nu
ON nu.user = u.id LEFT JOIN
nodes n
ON n.id = nu.node
WHERE c.pid = 999
GROUP BY c.id
ORDER BY c.created_at ASC;
This keeps everything in the first table, regardless of whether or not rows match in the subsequent tables. That appears to be what you want.

Query from 3 tables

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.

sql - How to have multiple select/from statements in one query

I'm trying to pull a report where each column is selecting from a specific table set. However, one of the columns needs to pull from a completely different table set and still be included in the same report. Of course, this doesn't work:
select u.first_name, ticket_work.time_spent
FROM tickets LEFT OUTER JOIN ticket_work ON ticket_work.ticket_id = tickets.id JOIN users u
(select count(tickets.id) FROM tickets JOIN users u)
where tickets.assigned_to = u.id
...
So just the part (select count(tickets.id) FROM tickets JOIN users u) needs to be selecting from the different table set but still be included in the report.
I'm a little confused by your question. Are you wanting to return the user, the count of tickets for that user, and the amount of time spent overall? If so, something like this should work:
select u.id, u.first_name,
SUM(tw.time_spent) summed_time_spent,
COUNT(DISTINCT t.id) count_tickets
FROM users u
LEFT JOIN tickets t
ON u.id = t.assigned_to
LEFT JOIN ticket_work tw
ON tw.ticket_id = t.id
GROUP BY u.id, u.first_name
Your questions is unclear, but just generally, it sounds like you're trying to join to a derived table (i.e., a query). In that case, do this:
SELECT...
FROM...
table_A A LEFT JOIN
(SELECT keyfield, valuefield FROM table_b WHERE ...) B
ON A.keyfield = B.keyfield
Does that make sense? To make a derived table, you put a query inside of parenthesis, give it an alias ('B' in this case), and then join it to your other tables as though it were a regular table.
Don't know about your table structure but you may use a sub query for such requirement
select u.first_name, ticket_work.time_spent,(select count(tickets.id) FROM tickets where ticket.id=ticket_work.ticket_id) as myCount
FROM tickets LEFT OUTER JOIN ticket_work ON ticket_work.ticket_id = tickets.id JOIN users u
where tickets.assigned_to = u.id

t-sql query that returns missing records

I have a query (ContactFormTypesRequired) that returns ContactID and FormTypeID utilizing related tables that are not shown below. This is a list of FormTypes that each Contact should have related to it as a Form.
I need a query that returns Contacts that do not have one or more related forms of the FormTypes specified in the above query.
I've tried a left outer join from Form to ContactsFormTypesRequired on FormTypeID, but the results don't take into account FormTypes that each specific Contact should have.
Please let me know if you have any questions.
Thank you in advance for any suggestions.
I am writing the query this way. This first starts with your query to get needed forms as a CTE, then cross joins them to Contacts to get every needed combination, before left joining to the actual forms.
with NeededForms (<yourqueryhere>)
select distinct c.*
from Contact c cross join
NeededForms nf left outer join
Form F
on nf.FormTypeId = f.FormTypeId left outer join
ContactForm cf
on c.ContactId = cf.ContactId and
f.FormId = cf.FormId
where cf.FormId is null
I'm doing it this way, so you can answer the query of what forms are missing with a very similar query:
with NeededForms (<yourqueryhere>)
select c.*, nf.FormTypeId
from Contact c cross join
NeededForms nf left outer join
Form F
on nf.FormTypeId = f.FormTypeId left outer join
ContactForm cf
on c.ContactId = cf.ContactId and
f.FormId = cf.FormId
where cf.FormId is null
Try this simple query using NOT IN Cluase:
SELECT * FROM Contact
WHERE ContactID IN
(SELECT ContactID FROM ContactForm
INNER JOIN FORM ON ContactForm.FormID=Form.FormID
WHERE FormTypeID=#FormTypeID)
I created ContactFormTypeExist:
SELECT DISTINCT Contact.ContactID, Form.FormTypeID
FROM Contact
INNER JOIN ContactForm
ON Contact.ContactID = ContactForm.ContactID
INNER JOIN Form
ON ContactForm.FormID = Form.FormID
Then joined ContactFormTypesRequired described in the question above to ContactFormTypeExist with outer join to give me the ConactIDs that are missing related FormTypeIDs:
SELECT ContactFormTypesRequired.ConactID
FROM ContactFormTypeExist
RIGHT JOIN ContactFormTypesRequired
ON (ContactFormTypeExist.FormTypeID = ContactFormTypesRequired.FormTypeID)
AND (ContactFormTypeExist.ConactID = ContactFormTypesRequired.ConactID)
WHERE (((ContactFormTypeExist.ConactID) Is Null));
This returns all the ContactID for Contacts missing FormTypes required by their ContactType.

SQL Query - Multiple Joins on Same field

I need assistance building this query where i need to select different values from same table but different Unique Keys.
To elaborate more ill provide the below example:
I have 2 tables:
Issues (IssueID, AuthorID_FK, AssigedID_FK, ... )
Users (UserID, User_Label, ... )
Both AuthorID_FK & AssigedID_FK are linked to table Users and i need to get in the same query result the User_Label for both.
Can you please assist?
Thanks,
SELECT a.IssueID, b.User_Label, c.User_Label FROM Issues a
INNER JOIN USERS b on a.AuthorID_FK = b.UserID
INNER JOIN USERS c on a.AssignedID_FK = c.UserID
something like that :) This should work in MS SQL Server
Well, this one should work too :)
SELECT IssueID, U.User_Label FROM Issues I
INNER JOIN Users U ON U.UserID = I.AuthorID_FK
UNION
SELECT IssueID, U.User_Label FROM Issues I
INNER JOIN Users U ON U.UserID = I.AssigedID_FK
Wont
SELECT a.IssueID, b.UserID
FROM Issues a
JOIN Users b ON (a.AuthorID_FK=b.UserID OR a.AssignedID_FK = b.UserID)
work?
You may want to try something like this
SELECT
issues.IssueID,
Authour.User_Label AS Author_Label,
Assigned.User_Label AS Assigned_user_Label
FROM
issues
INNER JOIN users AS Authour ON Authour.UserID = issues.AuthorID_FK
INNER JOIN users AS Assigned ON Assigned.UserID = issues.AssignedID_FK