Nhibernate hql left join - nhibernate

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

Related

SQL many to many select people with multiple vacancies

I am working with sql server through SSMS right now. How can i choose all people with multiple(>2)vacancies?
I am trying something like that, but i dont understand how to make part with "more than 2 vacancies"?
SELECT dbo.applicants.FirstName, dbo.vacancy.Name
FROM dbo.applicants INNER JOIN
dbo.VacancyApplicant ON dbo.applicants.id = dbo.VacancyApplicant.ApplicantId INNER JOIN
dbo.vacancy ON dbo.VacancyApplicant.VacancyId = dbo.vacancy.id WHERE dbo.vacancy.Name='third vacancy'
SELECT dbo.applicants.FirstName, dbo.vacancy.Name
FROM dbo.applicants A INNER JOIN
dbo.VacancyApplicant V ON A.id = V.ApplicantId
WHERE EXIST(
SELECT 1
FROM dbo.applicants INNER JOIN
dbo.VacancyApplicant ON dbo.applicants.id =
dbo.VacancyApplicant.ApplicantId INNER JOIN
dbo.vacancy ON dbo.VacancyApplicant.VacancyId = dbo.vacancy.id
WHERE A.id=dbo.applicants.id
GROUP BY dbo.applicants.id,dbo.vacancy.id
HAVING COUNT(1)>2
)
Group By and Having are you basic answer. Below is a simple solution, might not be ideal, but can give you the idea.
I am finding target "applicants" ids in subquery, that uses GROUP BY and HAVING then outer query joins to that to output FirstName and LastName of applicant
SELECT dbo.applicants.FirstName, dbo.applicants.LastName FROM
dbo.applicants a INNER JOIN
(
SELECT dbo.applicants.id
FROM dbo.applicants INNER JOIN
dbo.VacancyApplicant ON dbo.applicants.id = dbo.VacancyApplicant.ApplicantId INNER JOIN
dbo.vacancy ON dbo.VacancyApplicant.VacancyId = dbo.vacancy.id AND dbo.vacancy.Name='third vacancy'
GROUP BY dbo.applications.id
HAVING COUNT(dbo.vacancy.id) > 2
) targetIds ON a.id = targetIds.id
"more than 2 vacancies"?
Your question only mentions vacancies but your query is filtering for a particular name. I assume you really want more than two of that name.
If I understand correctly, you want aggregation:
SELECT a.FirstName, a.Name
FROM dbo.applicants a INNER JOIN
dbo.VacancyApplicant va
ON a.id = va.ApplicantId INNER JOIN
dbo.vacancy v
ON va.VacancyId = v.id
WHERE v.Name = 'third vacancy'
GROUP BY a.FirstName, v.Name
HAVING COUNT(*) > 2;
Note the use of table aliases. They make the query easier to write and to read.
WITH TempCTE AS (
SELECT DISTINCT ap.FirstName
,vc.Name
,COUNT (va.VacancyId) OVER (PARTITION BY ap.id) AS NoOfVacancies
FROM dbo.applicants ap
JOIN dbo.VacancyApplicant va
ON ap.id = va.ApplicantId
JOIN dbo.vacancy vc
ON va.VacancyId = vc.id
)
SELECT FirstName,[Name], NoOfVacancies FROM TempCTE
WHERE NoOfVacancies > 2

How to create distinct count from queries with several tables

I am trying to create one single query that will give me a distinct count for both the ActivityID and the CommentID. My query in MS Access looks like this:
SELECT
tbl_Category.Category, Count(tbl_Activity.ActivityID) AS CountOfActivityID,
Count(tbl_Comments.CommentID) AS CountOfCommentID
FROM tbl_Category LEFT JOIN
(tbl_Activity LEFT JOIN tbl_Comments ON
tbl_Activity.ActivityID = tbl_Comments.ActivityID) ON
tbl_Category.CategoryID = tbl_Activity.CategoryID
WHERE
(((tbl_Activity.UnitID)=5) AND ((tbl_Comments.PeriodID)=1))
GROUP BY
tbl_Category.Category;
I know the answer must somehow include SELECT DISTINCT but am not able to get it to work. Do I need to create multiple subqueries?
This is really painful in MS Access. I think the following does what you want to do:
SELECT ac.Category, ac.num_activities, aco.num_comments
FROM (SELECT ca.category, COUNT(*) as num_activities
FROM (SELECT DISTINCT c.Category, a.ActivityID
FROM (tbl_Category as c INNER JOIN
tbl_Activity as a
ON c.CategoryID = a.CategoryID
) INNER JOIN
tbl_Comments as co
ON a.ActivityID = co.ActivityID
WHERE a.UnitID = 5 AND co.PeriodID = 1
) as caa
GROUP BY ca.category
) as ca LEFT JOIN
(SELECT c.Category, COUNT(*) as num_comments
FROM (SELECT DISTINCT c.Category, co.CommentId
FROM (tbl_Category as c INNER JOIN
tbl_Activity as a
ON c.CategoryID = a.CategoryID
) INNER JOIN
tbl_Comments as co
ON a.ActivityID = co.ActivityID
WHERE a.UnitID = 5 AND co.PeriodID = 1
) as aco
GROUP BY c.Category
) as aco
ON aco.CommentId = ac.CommentId
Note that your LEFT JOINs are superfluous because the WHERE clause turns them into INNER JOINs. This adjusts the logic for that purpose. The filtering is also very tricky, because it uses both tables, requiring that both subqueries have both JOINs.
You can use DISTINCT:
SELECT
tbl_Category.Category, Count(DISTINCT tbl_Activity.ActivityID) AS CountOfActivityID,
Count(DISTINCT tbl_Comments.CommentID) AS CountOfCommentID
FROM tbl_Category LEFT JOIN
(tbl_Activity LEFT JOIN tbl_Comments ON
tbl_Activity.ActivityID = tbl_Comments.ActivityID) ON
tbl_Category.CategoryID = tbl_Activity.CategoryID
WHERE
(((tbl_Activity.UnitID)=5) AND ((tbl_Comments.PeriodID)=1))
GROUP BY
tbl_Category.Category;

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

SQL rows dissapear when join added

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

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