SQL rows dissapear when join added - sql

SELECT tblArtworkTemplates.ID, tblArtworkTemplates.dateCreated, tblSpecifications.TxtPagination, tblSpecifications.FlatSizeW AS width,
tblSpecifications.FlatSizeL AS length, tblSpecifications.FlatSizeUOM AS uom,
(SELECT COUNT(1) AS Expr1
FROM tblArtworkUploads
WHERE (templateID = tblArtworkTemplates.ID)) AS uploadCount,
(SELECT COUNT(1) AS talks
FROM tblArtworkTemplateMessages
WHERE (templateID = tblArtworkTemplates.ID)) AS talkCount, tblArtworkTemplates.lastEditPing, tblUsers.userName AS Expr1
FROM tblUsers INNER JOIN
tblArtworkTemplates INNER JOIN
tblSpecifications ON tblArtworkTemplates.specID = tblSpecifications.id ON tblUsers.id = tblArtworkTemplates.editPingUserID
WHERE (tblArtworkTemplates.userID = 70)
The tblusers join is causing rows to disapear when tblArtworkTemplates.editPingUserID is null. Am I using the wrong sort of join type?

Maybe try a left outer join.. Or a Right outer join..
Wikipedia for informations about join

Try this, your join was wrong.
SELECT tblArtworkTemplates.ID, tblArtworkTemplates.dateCreated, tblSpecifications.TxtPagination, tblSpecifications.FlatSizeW AS width,
tblSpecifications.FlatSizeL AS length, tblSpecifications.FlatSizeUOM AS uom,
(SELECT COUNT(1) AS Expr1
FROM tblArtworkUploads
WHERE (templateID = tblArtworkTemplates.ID)) AS uploadCount,
(SELECT COUNT(1) AS talks
FROM tblArtworkTemplateMessages
WHERE (templateID = tblArtworkTemplates.ID)) AS talkCount, tblArtworkTemplates.lastEditPing, tblUsers.userName AS Expr1
FROM tblUsers u
INNER JOIN tblArtworkTemplates a ON u.id = a.editPingUserID
INNER JOIN tblSpecifications s ON a.specID = s.id ON
WHERE (a.userID = 70)

It depends on what you are after.
If you always want records from tblUsers, but data from Template+Specification only where data is available from both (in other words, if a Template doesn't have a Specification, you don't care about the Template), use this
FROM tblUsers
LEFT JOIN
tblArtworkTemplates
INNER JOIN tblSpecifications
ON tblArtworkTemplates.specID = tblSpecifications.id
ON tblUsers.id = tblArtworkTemplates.editPingUserID
If you always want records from tblUsers, but data from Template if available, and then from Specification if available (in other words, if a Template is available that has no Specification, get data from the Template record anyway), then use this
FROM tblUsers
LEFT JOIN
tblArtworkTemplates
LEFT JOIN tblSpecifications
ON tblArtworkTemplates.specID = tblSpecifications.id
ON tblUsers.id = tblArtworkTemplates.editPingUserID
or more commonly written (since the 2 left joins are commutative)
FROM tblUsers
LEFT JOIN tblArtworkTemplates
ON tblUsers.id = tblArtworkTemplates.editPingUserID
LEFT JOIN tblSpecifications
ON tblArtworkTemplates.specID = tblSpecifications.id

Related

I need to group (tbl_types.name AS type) in a same row (postgres 14)

I need help with a select in postgres, I need to group X types into a single line, for example: type: multiple, trully, I need help on the type column
SELECT tbl_questions.id AS id,
tbl_questions.question AS question,
tbl_questions.year AS year,
tbl_question_responses.response_id AS response_id,
tbl_responses.response AS response_content,
tbl_responses.response_type AS response,
tbl_subjects.name AS subject,
tbl_categories.name AS category,
tbl_types.name AS type,
tbl_institutions.name AS institution
FROM tbl_questions
INNER JOIN tbl_question_responses ON tbl_questions.id = tbl_question_responses.question_id
INNER JOIN tbl_responses ON tbl_question_responses.response_id = tbl_responses.id
INNER JOIN tbl_question_subjects ON tbl_questions.id = tbl_question_subjects.question_id
INNER JOIN tbl_subjects ON tbl_subjects.id = tbl_question_subjects.subject_id
INNER JOIN tbl_question_categories ON tbl_questions.id = tbl_question_categories.question_id
INNER JOIN tbl_categories ON tbl_categories.id = tbl_question_categories.category_id
INNER JOIN tbl_question_types ON tbl_questions.id = tbl_question_types.question_id
INNER JOIN tbl_types ON tbl_types.id = tbl_question_types.type_id
INNER JOIN tbl_question_institutions ON tbl_question_institutions.question_id = tbl_questions.id
INNER JOIN tbl_institutions ON tbl_institutions.id = tbl_question_institutions.institution_id
WHERE tbl_questions.id = 'c7aa15cb-27e5-4f28-9141-483f7cce8e56'
This is a select result

How to select multiple many to many in relation with a single table

I'm currently working with database, but I've got stuck with a select query.
However, I'm not database expert.
The query should return the data from a table that has two relationships of many to many.
This is my tables Diagram that would shows the concept of my question
The Select Query should View three columns, which are VidTbl.Name, ActorTbl.Name and SubTitelTbl.name.
So, I've read and search in the Internet and I've given tries
First try
SELECT
VidTbl.NAME AS Video_Titel_Name,
ActorTbl.NAME AS Actor_Name
FROM ActorInVid
INNER JOIN VidTbl
ON VidTbl.Id = ActorInVid.FKVidId
INNER JOIN ActorTbl
ON ActorTbl.Id = ActorInVid.FKActorId
UNION all
SELECT
VidTbl.NAME AS Video_Titel_Name,
SubTitelTbl.NAME AS SubTitel_Langu
FROM SubTitelInVid
INNER JOIN VidTbl
ON VidTbl.Id = SubTitelInVid.FKVidId
INNER JOIN SubTitelTbl
ON SubTitelTbl.Id = SubTitelInVid.FKSTId
The Result I've got, it was wrong
Then I tried another way to solve this problem, but again I've got another error
second try
SELECT Temp1.*
From (SELECT VidTbl.Id AS Video_Id,
VidTbl.NAME AS Video_Titel_Name,
ActorTbl.NAME AS Actor_Name
FROM ActorInVid
INNER JOIN VidTbl
ON VidTbl.Id = ActorInVid.FKVidId
INNER JOIN ActorTbl
ON ActorTbl.Id = ActorInVid.FKActorId) AS Temp1
SELECT Temp2.*
FROM (SELECT VidTbl.Id AS Video_Id,
SubTitelTbl.NAME AS SubTitel_Langu
FROM SubTitelInVid
INNER JOIN VidTbl
ON VidTbl.Id = SubTitelInVid.FKVidId
INNER JOIN SubTitelTbl
ON SubTitelTbl.Id = SubTitelInVid.FKSTId) AS Temp2
SELECT *
FROM VidTbl
INNER JOIN Temp1
on Temp1.Video_Id = VidTbl.Id
INNER JOIN Temp2
on Temp2.Video_Id = VidTbl.Id
The error, I've got in the last select that was wrong
Thanks a lot for your help any ways
I wish that my question is clear and useful
Thanks again.
You are close. This should work...
SELECT
VidTbl.Name,
ActorTbl.Name,
SubTitelTbl.name
FROM VidTbl
INNER JOIN ActorInVid ON VidTbl.Id = ActorInVid.FKVidId
INNER JOIN ActorTbl ON ActorTbl.Id = ActorInVid.FKActorId
INNER JOIN SubTitelInVid ON VidTbl.Id = SubTitelInVid.FKVidId
INNER JOIN SubTitelTbl ON SubTitelTbl.Id = SubTitelInVid.FKSTId
SELECT DISTINCT vt.Name, at.Name, st.Name
FROM VidTbl vt
JOIN ActionInVid aiv ON aiv.VidId = vt.Id
JOIN SubtitleInVid siv ON siv.VidId = vt.Id
JOIN ActorTbl at ON at.Id = aiv.ActorId
JOIN SubTitleTbl st ON st.Id = siv.STId

translating sql sub query to join

I had a long query, I short it out by using joins instead and resultant query is as below but still it has sub query. How to convert this sub query to join
SELECT
pav.post_id as Id, img.path as Path, attr.name as Name, pc.title as Category, pav.value_text as Valuess, post.created_on as createdOn
FROM
postings post inner join post_attributes_values pav on post.post_id = pav.post_id
left outer join images img on post.post_id = img.post_id and img.sequence='1'
inner join attributes attr on pav.attr_id = attr.attr_id
inner join categories_parent_categories pc on attr.cat_id = pc.category_id
where
pav.post_id in (select distinct post_id from post_attributes_values where value_text = 'SFX')
After reading your last comment to Matei's answer I have come to realize that you actually want ALL the posts where one of the attributes has value of 'SFX'. If I understood correctly, your only alternative is to add derived table and join by post_id:
SELECT pav.post_id AS Id,
img.path AS Path,
attr.name AS Name,
pc.title AS Category,
pav.value_text AS Valuess,
post.created_on AS createdOn
FROM postings post
INNER JOIN post_attributes_values pav
ON post.post_id = pav.post_id
LEFT OUTER JOIN images img
ON post.post_id = img.post_id
AND img.sequence = '1'
INNER JOIN attributes attr
ON pav.attr_id = attr.attr_id
INNER JOIN categories_parent_categories pc
ON attr.cat_id = pc.category_id
INNER JOIN
(
SELECT DISTINCT post_id
FROM post_attributes_values
WHERE value_text = 'SFX'
) sfxPosts
ON pav.post_id = sfxPosts.post_id
(Query reformatted thanks to instant sql formatter.)
Maybe this? Please test it
SELECT
pav.post_id as Id, img.path as Path, attr.name as Name, pc.title as Category, pav.value_text as Valuess, post.created_on as createdOn
FROM
postings post
inner join post_attributes_values pav on post.post_id = pav.post_id AND pav.value_text = 'SFX'
left outer join images img on post.post_id = img.post_id and img.sequence='1'
inner join attributes attr on pav.attr_id = attr.attr_id
inner join categories_parent_categories pc on attr.cat_id = pc.category_id

Top 5 comments from a specific post. How to write my SQL

I want to show only the top 5 comments for a specific post (Like the post on facebook where people cant comment them).
gbn was kind enough to help figure out that issue by doing the following:
select
*
FROM
tblPost P
OUTER APPLY
(SELECT TOP 5 * FROM tblComment C
WHERE P.id = C.postid
ORDER BY something) inline
But since I'm no sql grand master I would need your help to put that into my real sql statement.
SELECT *
FROM
memberactions INNER JOIN
actions ON memberactions.actionid = actions.id INNER JOIN
members ON memberactions.memberid = members.id LEFT OUTER JOIN
members members_2 INNER JOIN
actioncomments ON members_2.id = actioncomments.memberid INNER JOIN
comments ON actioncomments.commentid = comments.id ON actions.id = actioncomments.actionid
So my question is could you rearrange my sql to put the OUTER APPLY in my real sql statement.
Assuming that my table comments reprensent tblComment and that actioncomments represent the table tblPost
There does not seem to be a need for the member_2 table at all, but this is a faithful representation of what you had (preserving member_2)
SELECT *
FROM memberactions
INNER JOIN actions
ON memberactions.actionid = actions.id
INNER JOIN members
ON memberactions.memberid = members.id
OUTER APPLY (
select top(5) *
FROM actioncomments
inner join comments ON actioncomments.commentid = comments.id
inner join members members_2 ON members_2.id = actioncomments.memberid
WHERE actions.id = actioncomments.actionid
order by comments.id desc) comments
SELECT *
FROM
memberactions
INNER JOIN actions
ON memberactions.actionid = actions.id
INNER JOIN members
ON memberactions.memberid = members.id
LEFT OUTER JOIN members members_2
INNER JOIN actioncomments
ON members_2.id = actioncomments.memberid
OUTER APPLY
(SELECT TOP 5 * FROM comments C
WHERE actioncomments.commentid = comments.id
ORDER BY something)
ON actions.id = actioncomments.actioni
still don't know what you want to order by

Nhibernate hql left join

Is it possible to do a left join like this in Nhibernate:
SELECT T.title_id, T.title, S.qty
FROM titles T
LEFT JOIN sales S on
T.title_id = S.title_id
AND S.stor_id = '7131'
ORDER BY T.title
The important part to note is the extra clause (AND S.stor_id = '7131') in the LEFT JOIN expression.
Can I do this in Nhibernate hql or is there another way?
The answer is the with keyword, for example:
Select q FROM GeneralQuestion
q Left Join q.QuestionResponses as qr with
qr.ContactUid = :contactuid WHERE q.ParentUid = :audituid