LINQ Joins on nullable column - vb.net

I am not very good with linq, seems kind of confusing to me, but I have been making my way through it. I have the following query that I can't seem to get to work.
I get the error:
The value for column 'empl_cctr_id' in table 'temsempl' is dbnull.
The other join might also get the same error as well but with that related tables. Please help.
Dim query = (From empl In EMS_DS.TEMSEMPL
Join cctr In EMS_DS.TEMSCCTR On empl.empl_cctr_id Equals cctr.cctr_id
Join ppcd In EMS_DS.TEMSPPCD On empl.empl_ppcd_id Equals ppcd.ppcd_id
Where empl.empl_userid.Equals(text.ToString.ToUpper)
Select empl.empl_sep_dt, cctr.cctr_cd, ppcd.ppcd_desc).ToList

Dim query = (From empl In EMS_DS.TEMSEMPL
Join cctr In EMS_DS.TEMSCCTR On empl.empl_cctr_id Equals cctr.cctr_id into temp
from cctr in temp.DefaultIfEmpty()
Join ppcd In EMS_DS.TEMSPPCD On empl.empl_ppcd_id Equals ppcd.ppcd_id
Where empl.empl_userid.Equals(text.ToString.ToUpper)
Select empl.empl_sep_dt, cctr.cctr_cd, ppcd.ppcd_desc).ToList

Related

Linq group join failing, if the result has empty rows

I'm quite new to using Linq queries, and I'm trying to do a group join between two data tables ( to simulate a left join in sql ), which is failing if some of the rows miss values.
I've tried the query below:
(From date_amotiq
In amotiq_data_dt.AsEnumerable
Group Join v05_va33_data In v05_join_va33_zalvunloading.AsEnumerable
On date_amotiq("MATNR").ToString Equals v05_va33_data("ALV_PN").ToString
And date_amotiq("KDMAT").ToString Equals v05_va33_data("CUST_PN").ToString
And date_amotiq("UIP_Formatted").ToString
Equals v05_va33_data("Unloading_Point").ToString Into main_sht_data = Group
From v05_va33_data in main_sht_data.DefaultIfEmpty()
Select main_sheet_dt.Clone.LoadDataRow(New Object()
{"RO1W",
date_amotiq("MATNR"), date_amotiq("KDMAT"),date_amotiq("UIP_Formatted"),
date_amotiq("RDATUM"), "",
main_sht_data.FirstOrDefault().Item(0)
},False))
.CopyToDataTable
I know that "main_sht_data" is generated as an enumerable and I've tried to get the values with FirstOrDefault and ElementOrDefault, which return a datarow, but it fails as soon as I hit an empty row.
Could you please assist?
I managed to get it working by using if(v05_va33_data is nothing,"",v05_va33_data("Sales_Doc_Type"), and so on, for all fields which could be empty.

Access SQL query without duplicate results

I made a query and wanted to not have any duplicates but i got some times 3 duplicates and when i used DISTINCT or DISTINCTROW i got only 2 duplicates.
SELECT f.flight_code,
f.status,
a.airport_name,
a1.airport_name,
f.departing_date+f.departing_time AS SupposedDepartingTime,
f.landing_date+f.landing_time AS SupposedLandingTime,
de.actual_takeoff_date+de.actual_takeoff_time AS ActualDepartingTime,
SupposedLandingTime+(ActualDepartingTime-SupposedDepartingTime) AS ActualLandingTime
FROM
(((Flights AS f
LEFT JOIN Aireports AS a
ON a.airport_code = f.depart_ap)
LEFT JOIN Aireports AS a1
ON f.target_ap = a1.airport_code)
LEFT JOIN Irregular_Events AS ie
ON f.flight_code = ie.flight_code)
LEFT JOIN Delay_Event AS de
ON ie.IE_code = de.delay_code;
had to use LEFT JOIN because when i used INNER JOIN i missed some of the things i wanted to show because i wanted to see all the flights and not only the flights that got delayed or canceled.
This is the results when i used INNER JOIN, you can see only the flights that have the status "ביטול" or "עיכוב" and that is not what i wanted.
[the results with LEFT JOIN][2]
[2]: https://i.stack.imgur.com/cgE2G.png
and when i used DISTINCT where you see the rows with the NUMBER 6 on the first column it appear only two times
IMPORTANT!
I just checked my query and all the tables i use there and i saw my problem but dont know how to fix it!
in the table Irregular_Events i have more the one event for flights 3,6 and 8 and that is why when i use LEFT JOIN i see more even thou i use distinct, please give me some help!
Not entirely sure without seeing the table structure, but this might work:
SELECT f.flight_code,
f.status,
a.airport_name,
a1.airport_name,
f.departing_date+f.departing_time AS SupposedDepartingTime,
f.landing_date+f.landing_time AS SupposedLandingTime,
de.actual_takeoff_date+de.actual_takeoff_time AS ActualDepartingTime,
SupposedLandingTime+(ActualDepartingTime-SupposedDepartingTime) AS ActualLandingTime
FROM
((Flights AS f
LEFT JOIN Aireports AS a
ON a.airport_code = f.depart_ap)
LEFT JOIN Aireports AS a1
ON f.target_ap = a1.airport_code)
LEFT JOIN
(
SELECT
ie.flight_code,
de1.actual_takeoff_date,
de1.actual_takeoff_time
FROM
Irregular_Events ie
INNER JOIN Event AS de1
ON ie.IE_code = de1.delay_code
) AS de
ON f.flight_code = de.flight_code
It is hard to tell what is the problem with your query without any sample of the output, and without any description of the structure of your tables.
But your problem is that your are querying from the flights table, which [I assume] can be linked to multiple irregular_events, which can possibly also be linked to multiple delay_event.
If you want to get only one row per flight, you need to make sure your joins return only one row too. Maybe you can do it by adding one more condition to the join, or by adding a condition in a sub-query.
EDIT
You could try to add a GROUP BY to the query:
GROUP BY
f.flight_code,
f.status,
a.airport_name,
a1.airport_name;

Using LinQ with group by more than one column

I'm Newbi in LinQ, I have problem with group by in linQ.
I wan to query like this:
select
MAX(TCheckpointGrouping.Id) AS CheckpointGroupingId,
MAX(TCheckpointGrouping.MCheckpointId) AS CheckpointId,
MAX(MCheckpoint.Name) AS CheckpointName,
MAX(CAST(MCheckpoint.IsMajor AS VARCHAR)) AS IsMajor,
MAX(TCheckpointGrouping.MIndicatorId) AS IndicatorId,
MAX(MIndicator.Name) AS IndicatorName,
MAX(MCriteria.Id) AS CriteriaId,
MAX(MCriteria.Name) AS CriteriaName,
MAX(MPrinciple.Id) AS PrincipleId,
MAX(MPrinciple.Name) AS PrincipleName,
MAX(TCheckpointGrouping.RelationToCheckPoint) AS RelationToCheckPoint
from TCheckpointGrouping
inner join MCheckpoint on MCheckpoint.Id = TCheckpointGrouping.MCheckpointId
inner join MIndicator on MIndicator.Id = TCheckpointGrouping.MIndicatorId
inner join MCriteria on MCriteria.Id = MIndicator.MCriteriaId
inner join MPrinciple on MPrinciple.Id = MCriteria.MPrincipleId
group by
TCheckpointGrouping.MCheckpointId,
TCheckpointGrouping.MIndicatorId
How can i convert query above into LinQ (VB.NET)
thanks
bestRegards
I'm tempted to convert this SQL query to LINQ for you, but I think that would be a waste of opportunity for you to learn yourself.
There's a great page from Microsoft with lot of VB.NET Linq situations: 101 Linq Samples.
You can even find an example of a Group By using Multiple Columns.
Good learning. :)
I am not sure about this, but you can try it. In select part i have not included all the columns.
var result= from TChkgp in TCheckpointGrouping
join MCpoint in MCheckpoint on TChkgp.Id equals MCpoint.Id
join MIndtor in MIndicator on TChkgp.MIndicatorId equals MIndtor.Id
join MCrteia in MCriteria on MIndtor.Id equals MIndtor.MCriteriaId
join MPrncple in MPrinciple on MCrteia.MPrincipleId equals MPrncple.Id
group TChkgp by new (TChkgp.MCheckpointId,TChkgp.MIndicatorId} into g
select new {
CheckpointGroupingId =TChkgp.Id.Max(),
CheckpointId =TChkgp.MCheckpointId.Max,
....
....
};
you can see one simple example on following link
Group and sum in linq

Whats wrong with this nested query?

I am trying to write a query to return the id of the latest version of a market index stored in a database.
SELECT miv.market_index_id market_index_id from ref_market_index_version miv
INNER JOIN ref_market_index mi ON miv.market_index_id = mi.id
WHERE mi.short_name='dow30'
AND miv.version_num = (SELECT MAX(m1.version_num) FROM ref_market_index_version m1 INNER JOIN ref_market_index m2 ON m1.market_index_id = m2.id )
The above SQL statement can be (roughly) translated into the form:
SELECT some columns FROM SOME CRITERIA MATCHED TABLES
WHERE mi.short_name='some name'
AND miv.version_num = SOME NUMBER
What I don't understand is that when I supply an actual number (instead of a sub query), the SQL statement works - also, when I test the SUB query used to determine the latest version number, that also works - however, when I attempt to use the result returned by sub query in the outer (parent?) query, it returns 0 rows - what am I doing wrong here?
Incidentally, I also tried an IN CLAUSE instead of the strict equality match i.e.
... AND miv.version_num IN (SUB QUERY)
That also resulted in 0 rows, although as before, when running the parent query with a hard coded version number, I get 1 row returned (as expected).
BTW I am using postgeresql, but I prefer the solution to be db agnostic.
The problem is probably that the max(version_num) doesn't exist for 'dow30'.
Try the following correlated subquery:
SELECT miv.market_index_id market_index_id
from ref_market_index_version miv INNER JOIN
ref_market_index mi
ON miv.market_index_id = mi.id
WHERE mi.short_name='dow30' AND
miv.version_num = (SELECT MAX(m1.version_num)
FROM ref_market_index_version m1 INNER JOIN
ref_market_index m2
ON m1.market_index_id = m2.id
where m1.short_name = 'dow30'
)
I added the where clause in the subquery.

sql query question inner join

LEFT JOIN PatientClinics AB ON PPhy.PatientID = AB.PatientID
JOIN Clinics CL ON CL.ID = AB.ClinicID
AND COUNT(AB.ClinicID) = 1
I get error using Count(AB.ClinicID) = 1 (ClinicID has duplicate values in the table and
I want to use only 1 value of each duplicate value of ClinicId to produce result)
What mistake am I making?
I've never seen a COUNT() being used in a JOIN before. Maybe you should use:
HAVING COUNT(AB.ClinicID) = 1
instead.
Count() can't be used as a join/filter predicate. It can be used in the HAVING clause however. You should include the entire query in order to get a better example of how to rewrite it.
maybe investigate the HAVING clause instead of using COUNT where you put it.
hard to help without the full query.