How do you use group by and having clause in EF with parent/child relationship? - entity-framework

How can I write a linq to entities query that includes a group by and a having clause?
For example in SQL:
SELECT * FROM dbo.tblParent p
INNER JOIN
(
SELECT a.ID
FROM dbo.tblParent a
join dbo.tblChild c ON a.ID = c.FkParentID
WHERE a.ColValue = 167
GROUP BY A.ID
HAVING COUNT(c.ID) = 1
) t ON p.ID = t.ID

I found my own answer.
// this is far from pretty but it works as far as I can tell
Apps = (from x in context.tblParents
join t in (
from p in context.tblParents
join c in context.tblChilds
on p.ID equals c.FkParentID
where p.ColValue == 167
group c.ID by p.ID into grouped
where grouped.Count() == 1
select new { grouped.Key }) on x.ID equals t.Key
select x);

Related

Replace subquery with appropriate join

how can i remove subquery with a join?
SELECT distinct t."groupId" FROM "contacts" c
INNER JOIN
(
SELECT DISTINCT td.* FROM "groups" g
INNER JOIN
"territory" td
ON
td."groupId" = g.id
WHERE g."orgId" = 3
)
t
ON
ST_Intersects(t.points, c."geoPoint")
WHERE c.id = 33 and c."orgId" = 3
There is nothing wrong with a subquery, but you should get rid of the dreaded DISTINCT:
SELECT td."groupId"
FROM territory AS td
WHERE EXISTS (SELECT 1 FROM contacts AS c
WHERE ST_Intersects(td.points, c."geoPoint")
AND c.id = 33
AND c."orgId" = 3)
AND EXISTS (SELECT 1 FROM groups AS g
WHERE td."groupId" = g.id
AND g."orgId" = 3);
If you insist in having no subqueries, use
SELECT DISTINCT t."groupId"
FROM contacts c
INNER JOIN territory td
ON ST_Intersects(td.points, c."geoPoint")
INNER JOIN groups g
ON td."groupId" = g.id
WHERE g."orgId" = 3
AND c.id = 33
AND c."orgId" = 3;
If you need to make sure that the st_intersects function is only called for rows from territory that match the join with groups, you will have to use a subquery. There is no other way to force a join order.

How to add id sequence from select query in postgresql

I would like to add sequence id after I select data from more than one table
this is my query:
SELECT DISTINCT a.value_suggested_row, c.id as question_id, c.question, b.value
from survey_user_input_line a
LEFT JOIN survey_label b on b.id = a.value_suggested_row
LEFT JOIN survey_question c on c.id = a.question_id
where survey_id = 6
ORDER BY question_id
and this is the result
how to do the correct query to add the id sequence to the query so that the results are like this
Can Anyone help me, please?
In the select list add ROW_NUMBER () OVER (ORDER BY question_id) as id_sequence
SELECT DISTINCT #rownum:=#rownum+1 id_sequence, a.value_suggested_row, c.id as
question_id, c.question, b.value
from survey_user_input_line a
LEFT JOIN survey_label b on b.id = a.value_suggested_row
LEFT JOIN survey_question c on c.id = a.question_id
where survey_id = 6
ORDER BY question_id, (SELECT #rownum:=0) r;

Return records if all conditions Match

I need a query to return records if all conditions Match.
Example:
Lets say I have a User “John” (UserID: '37') that belongs to groups 'A','B','C' (GroupID: '47', '48', '166')
And I type
Select person, group
from persons p inner join groups g
on p.id = g.id
where p.id = '37'
and g.id in ('47','166')
The query should return No Record because not all conditions match, Group 'C' was not part of the query.
How can I do this?
This has to be a dup but I cannot find it
Select p.id
from persons p inner join groups g
on p.id = g.UserID
where p.id = '37'
and g.GroupID in ('47','166')
group by person
having count(*) = 2
--The subquery did what I was after
SELECT p.id, g.id
FROM persons p inner join groups g
on p.id = g.Userid
where g.Userid =
(select Userid from groups gs
where p.id = gs.Userid
And gs.id in (47,166)
group by g.Userid
having count(distinct gs.id) = 3)

Filter table that I do a LEFT JOIN with

Here's my query at the moment:
SELECT A.*
FROM A
LEFT JOIN B ON B.a_id = A.id
Now, suppose there is a table C which relates directly to B. What I'd like to do is to filter out the records of table B based on C - how do I do that? I've tried placing the filter in the WHERE section:
SELECT A.*
FROM A
LEFT JOIN B ON B.a_id = A.id
LEFT JOIN C ON B.c_id = C.id
WHERE C.id > 10
The problem is that the preceding queryalso filters out table A's results. How do I achieve the result that I want?
you need to put that filter in join :
SELECT *
FROM A
LEFT JOIN
(
SELECT B.*
FROM B
INNER JOIN C ON B.c_id = C.id AND C.id > 10
) AS B ON B.a_id = A.id
it will not filter out the A's results .

Using multiple resultsets combined with joins in T-SQL

I'm currently using joins inside my stored procedures for outputting elements from different tables. An aggressive example
select a.*, b.*, c.*, d.*, e.*, f.* from tableA a
join tableB b on a.id = b.foreignid
join tableC c on b.id = c.foreignid
join tableD d on c.id = d.foreignid
join tableE e on d.id = e.foreignid
join tableF f on e.id = f.foreignid
where a.id = 1
It's getting pretty unhandy to work with when mapping the output to entities in my C# code, since I have to maintain a lot of boilerplate code.
Instead I would look into using multiple resultsets, so that I could map each resultset into an object type in code.
But how would I go around achieving this when I my case the different results would all relate to each other? The examples I've been able to find all revolved around selecting from different tables where the data were not related by foreign keys like mine. If I were to ouput my result in multiple resultsets the only thing I can come up with is something like this
select a.* from tableA
where a.id = 1
select b.* from tableB
join tableA a on a.id = b.foreignid
where a.id = 1
select c.* from tableC
join tableB b on b.id = c.foreignid
join tableA on a.id = b.foreginid
where a.id = 1
select d.* from tableD
join tableC c on c.id = d.foreignid
join tableB b on b.id = c.foreignid
join tableA a on a.id = b.foreignid
where a.id = 1
select e.* from tableE
join tableD d on d.id = e.foreignid
join tableC c on c.id = d.foreignid
join tableB b on b.id = c.foreignid
join tableA a on a.id = b.foreignid
where a.id = 1
select f.* from tableF
join tableE e on e.id = f.foreignid
join tableD d on d.id = e.foreignid
join tableC c on c.id = d.foreignid
join tableB b on b.id = c.foreignid
join tableA a on a.id = b.foreignid
where a.id = 1
But this is not cleaner, a lot more ineffecient (I would suppose, since there's alot more join statements)
Is it possible to use multiple resultset in this way I'm trying to? I just don't know how I would write the sql statements in the stored proc without having to do massive joins per resultset as in the example. And with the current solution I get an explosion of columns since I join them all together
You can actually return multiplte resultsets from a single SP and consume them in c#, check this post for instance : http://blogs.msdn.com/b/dditweb/archive/2008/05/06/linq-to-sql-and-multiple-result-sets-in-stored-procedures.aspx
It's a lesser known feature but sounds like what you're asking for. You don't have to join them and return them as a flattend rowset, just get the seperate rowsets and piece them together in memory.
Also you may want to read up on ORM frameworks, that could save you a lot of typing that you coud spend on features if it fits your needs.
https://stackoverflow.com/questions/249550/what-orm-frameworks-for-net-do-you-like-best
Regards GJ