Linq query only returning 1 row - linq

Dim ds = From a In db.Model
Join b In db.1 On a.id Equals b.ID
Join c In db.2 On a.id Equals c.ID
Join d In db.3 On a.id Equals d.ID
Join f In db.4 On a.id Equals f.ID
Select a.id, a.Ref, a.Type, a.etc
Above is my linq query. At the moment I am only getting the first row from the db returned when there are currently 60 rows. Please can you tell me where I am going wrong and how to select all records.
Thanks in advance!
UPDATE:
When I take out all the joins like so:
Dim ds = From a In db.1, b In db.2, c In db.3, d In db.4, f In db.5
Select a.id, a.Ref, a.type, b.etc, c.etc, d.etc
I get a system.outofmemory exception!

You're only going to get a row produced when all of the joins match - in other words, when there's a row from Model with an AP, an Option, a Talk and an Invoice. My guess is that there's only one of those.
LINQ does an inner join by default. If you're looking for a left outer join (i.e. where a particular row may not have an Invoice, or a Talk etc) then you need to use a group join, usually in conjunction with DefaultIfEmpty.
I'm not particularly hot on VB syntax, but this article looks like it's what you're after.

Related

how to use full outer join writing query on multiple tables?

I have a below query
How to use full outer join for TABLE T4 for getting all records?
WHERE
(DB.T4.AUTH_REV_NO=DB.T2.AUTH_REV_NO
AND DB.T4.AUTH_NO=DB.T2.AUTH_NO)
AND (DB.T2.AUTH_CURR_IN='Y' )
AND (DB.T3.AUTH_NO=DB.T2.AUTH_NO)
AND (DB.T3.AUTH_REV_NO=DB.T2.AUTH_REV_NO )
AND (DB.T6.FNC_ID=DB.T4.FNC_ID)
AND (DB.T7.FNC_SEG_ID=DB.T6.FNC_SEG_ID)
AND (DB.T1.SCT_ID(+)=DB.T7.SCT_ID
AND DB.T1.FNC_SEG_ID(+)=DB.T7.FNC_SEG_ID)
AND (DB.T8.NDE_ID=DB.T12.NDE_ID)
AND (DB.T7.FNC_SEG_ID=DB.T8.FNC_SEG_ID)
AND (DB.T7.SCT_ID=DB.T8.SCT_ID)
AND ((DB.T12.NDE_ID=DB.T6.NDE_STRT_ID)
OR (DB.T12.NDE_ID=DB.T6.NDE_END_ID))
AND (DB.T5.FNC_ID(+)=DB.T4.FNC_ID)
AND (T13_A4.REF_ID(+)=DB.T5.REF_TONE_TYP_ID)
AND (fne.FNC_SEG_ID=DB.T8.FNC_SEG_ID)
AND (fne.NDE_ID=DB.T8.NDE_ID)
AND (fne.SCT_ID=DB.T8.SCT_ID)
AND fnode.NDE_ID=DB.T6.NDE_STRT_ID
AND tnode.NDE_ID=DB.T6.NDE_END_ID
AND (DB.T4.REF_FNC_TYP_ID=T13_A1.REF_ID)
AND (ne_port.NDE_EQP_ID=fne.NDE_EQP_ID)
AND (ne_port.NDE_EQP_PRN_ID=ne_card.NDE_EQP_ID)
AND (ne_card.NDE_EQP_PRN_ID=ne_shelf.NDE_EQP_ID)
AND (ne_shelf.NDE_EQP_PRN_ID=ne_rack.NDE_EQP_ID)
AND (eq.EQP_ID=ne_card.EQP_ID)
AND (eq.REF_EQP_CLS_ID=T13_A2.REF_ID)
AND (DB.T3.REF_AUTH_STS_ID=T13_A3.REF_ID)
AND (DB.T3.AUTH_STS_ID
IN (SELECT MAX(DB.T3.AUTH_STS_ID) FROMDB.T3
WHERE (DB.T3.AUTH_NO,DB.T3.AUTH_REV_NO)
IN
(SELECT
DB.T3.AUTH_NO,
MAX(DB.T3.AUTH_REV_NO)
FROM
DB.T3
GROUP BY
DB.T3.AUTH_NO)
GROUP BY
DB.T3.AUTH_NO))
How to use full outer join for TABLE T4 and for COLUMN FNC_TONE_LVL_QT to get all records.
Please help.
You posted a whole lot of "joins". I'm not going to rewrite it for you, but - I'd suggest you to switch to a more recent explicit JOIN syntax which makes things somewhat simpler and easier to understand as you'd separate joins from conditions. Moreover, it allows you to outer join the same table to more than just one another table, which is impossible with the old (+) Oracle's outer join operator.
Something like this
select ...
from table_1 a left join table_2 b on a.id = b.id
full outer join table_3 c on c.id = a.id
...

HQL some tables are joined some are not - please explain

I have come across some hql that looks like this:
select a.id
from something a inner join a.whatever b,
somethingelse c inner join c.blah d
where a.id = c.id
Why is a inner joined to b and c inner joined to d but a is linked to c via where
What exactly is this hql saying? Please explain in simple terms.
This query means that the a and b are related in the model. Same is the case with c and d.
In order to join a and c, you have to explicitly state the join field, i.e., id since the model does not have this information.

Linq-to-SQL left join on left join/multiple left joins in one Linq-to-SQL statement

I'm trying to rewrite SQL procedure to Linq, it all went well and works fine, as long as it works on small data set. I couldn't really find answer to this anywhere. Thing is, I have 3 joins in the query, 2 are left joins and 1 is inner join, they all join to each other/like a tree. Below you can see SQL procedure:
SELECT ...
FROM sprawa s (NOLOCK)
LEFT JOIN strona st (NOLOCK) on s.ident = st.id_sprawy
INNER JOIN stan_szczegoly ss (NOLOCK) on s.kod_stanu = ss.kod_stanu
LEFT JOIN broni b (NOLOCK) on b.id_strony = st.ident
What I'd like to ask you is a way to translate this to Linq. For now I have this:
var queryOne = from s in db.sprawa
join st in db.strona on s.ident equals st.id_sprawy into tmp1
from st2 in tmp1.DefaultIfEmpty()
join ss in db.stan_szczegoly on s.kod_stanu equals ss.kod_stanu
join b in db.broni on st2.ident equals b.id_strony into tmp2
from b2 in tmp2.DefaultIfEmpty()
select new { };
Seems alright, but when checked with SQL Profiler, query that is sent to database looks like that:
SELECT ... FROM [dbo].[sprawa] AS [Extent1]
LEFT OUTER JOIN [dbo].[strona] AS [Extent2]
ON [Extent1].[ident] = [Extent2].[id_sprawy]
INNER JOIN [dbo].[stan_szczegoly] AS [Extent3]
ON [Extent1].[kod_stanu] = [Extent3].[kod_stanu]
INNER JOIN [dbo].[broni] AS [Extent4]
ON ([Extent2].[ident] = [Extent4].[id_strony]) OR
(([Extent2].[ident] IS NULL) AND ([Extent4].[id_strony] IS NULL))
As you can see both SQL queries are bit different. Effect is the same, but latter works incomparably slower (less than a second to over 30 minutes). There's also a union made, but it shouldn't be the problem. If asked for I'll paste code for it.
I'd be grateful for any advice on how to better the performance of my Linq statement or how to write it in a way that is translated properly.
I guess I found the solution:
var queryOne = from s in db.sprawa
join st in db.strona on s.ident equals st.id_sprawy into tmp1
where tmp1.Any()
from st2 in tmp1.DefaultIfEmpty()
join ss in db.stan_szczegoly on s.kod_stanu equals ss.kod_stanu
join b in db.broni on st2.ident equals b.id_strony into tmp2
where tmp2.Any()
from b2 in tmp2.DefaultIfEmpty()
select new { };
In other words where table.Any() after each into table statement. It doesn't make translation any better but has sped up execution time from nearly 30minutes(!) to about 5 seconds.
This has to be used carefully though, because it MAY lead to losing some records in result set.

Hive doesn't support in, exists. How do I write the following query?

I have two tables A and B that both have a column id. I wish to obtain ids from A that are not present in B. The obvious way is:
SELECT id FROM A WHERE id NOT IN (SELECT id FROM B)
Unfortunately, Hive doesn't support in, exists or subqueries. Is there a way to achieve the above using joins?
I thought of the following
SELECT A.id FROM A,B WHERE A.id<>B.id
But it seems like this will return the entirety of A, since there always exists an id in B that is not equal to any id in A.
You can do the same with a LEFT OUTER JOIN in Hive:
SELECT A.id
FROM A
LEFT OUTER JOIN B
ON (B.id = A.id)
WHERE B.id IS null
Hive seems to support IN, NOT IN, EXIST and NOT EXISTS from 0.13.
select count(*)
from flight a
where not exists(select b.tailnum from plane b where b.tailnum = a.tailnum);
The subqueries in EXIST and NOT EXISTS should have correlated predicates (like b.tailnum = a.tailnum in above sample)
For more, refer Hive Wiki > Subqueries in the WHERE Clause
Should you ever want to do an IN as so:
SELECT id FROM A WHERE id IN (SELECT id FROM B)
Hive has this covered with a LEFT SEMI JOIN:
SELECT a.key, a.val
FROM a LEFT SEMI JOIN b on (a.key = b.key)
if you can using spark sql you can use left anti join.
ex: SELECT A.id FROM A left anti join B on a.id=b.id

LINQ nested joins

Im trying to convert a SQL join to LINQ. I need some help in getting the nested join working in LINQ.
This is my SQL query, Ive cut it short just to show the nested join in SQL:
select distinct
txtTaskStatus as TaskStatusDescription,
txtempfirstname+ ' ' + txtemplastname as RaisedByEmployeeName,
txtTaskPriorityDescription as TaskPriorityDescription,
dtmtaskcreated as itemDateTime,
dbo.tblTask.lngtaskid as TaskID,
dbo.tblTask.dtmtaskcreated as CreatedDateTime,
convert(varchar(512), dbo.tblTask.txttaskdescription) as ProblemStatement,
dbo.tblTask.lngtaskmessageid,
dbo.tblMessage.lngmessageid as MessageID,
case when isnull(dbo.tblMessage.txtmessagesubject,'') <> '' then txtmessagesubject else left(txtmessagedescription,50) end as MessageSubject,
dbo.tblMessage.txtmessagedescription as MessageDescription,
case when dbo.tblMessage.dtmmessagecreated is not null then dbo.tblMessage.dtmmessagecreated else CAST(FLOOR(CAST(dtmtaskcreated AS DECIMAL(12, 5))) AS DATETIME) end as MessageCreatedDateTime
FROM
dbo.tblAction RIGHT OUTER JOIN dbo.tblTask ON dbo.tblAction.lngactiontaskid = dbo.tblTask.lngtaskid
LEFT OUTER JOIN dbo.tblMessage ON dbo.tblTask.lngtaskmessageid = dbo.tblMessage.lngmessageid
LEFT OUTER JOIN dbo.tblTaskCommentRecipient
RIGHT OUTER JOIN dbo.tblTaskComment ON dbo.tblTaskCommentRecipient.lngTaskCommentID = dbo.tblTaskComment.lngTaskCommentID
ON dbo.tblTask.lngtaskid = dbo.tblTaskComment.lngTaskCommentTaskId
A more seasoned SQL programmer wouldn't join that way. They'd use strictly left joins for clarity (as there is a strictly left joining solution available).
I've unraveled these joins to produce a hierarchy:
Task
Action
Message
TaskComment
TaskCommentRecipient
With associations created in the linq to sql designer, you can reach these levels of the hierarchy:
//note: these aren't outer joins
from t in db.Tasks
let actions = t.Actions
let message = t.Messages
let comments = t.TaskComments
from c in comments
let recipients = c.TaskCommentRecipients
DefaultIfEmpty produces a default element when the collection is empty. Since these are database rows, a default element is a null row. That is the behavior of left join.
query =
(
from t in db.Tasks
from a in t.Actions.DefaultIfEmpty()
from m in t.Messages.DefaultIfEmpty()
from c in t.Comments.DefaultIfEmpty()
from r in c.Recipients.DefaultIfEmpty()
select new Result()
{
TaskStatus = ???
...
}
).Distinct();
Aside: calling Distinct after a bunch of joins is a crutch. #1 See if you can do without it. #2 If not, see if you can eliminate any bad data that causes you to have to call it. #3 If not, call Distinct in a smaller scope than the whole query.
Hope this helps.
SELECT [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate], [t0].[RequiredDate], [t0].[ShippedDate], [t0].[ShipVia], [t0].[Freight], [t0].[ShipName], [t0].[ShipAddress], [t0].[ShipCity], [t0].[ShipRegion], [t0].[ShipPostalCode], [t0].[ShipCountry]
FROM [Orders] AS [t0]
LEFT OUTER JOIN ([Order Details] AS [t1]
INNER JOIN [Products] AS [t2] ON [t1].[ProductID] = [t2].[ProductID]) ON [t0].[OrderID] = [t1].[OrderID]
can be write as
from o in Orders
join od in (
from od in OrderDetails join p in Products on od.ProductID equals p.ProductID select od)
on o.OrderID equals od.OrderID into ood from od in ood.DefaultIfEmpty()
select o

Resources