Linq group join failing, if the result has empty rows - vb.net

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.

Related

MS Access SQL sub Query using outer query result

I'm attempting to run a sub query based on the result of an outer query. The issue that I am having is that instead of using the outer query, I get a prompt for a value from the subquery.
SELECT Facilities.CustomerName, Facilities.FacilityName,
Facilities.AnnualPlan, Facilities.AppCo1,
(SELECT YeildDB.CornYield
FROM YeildDB
WHERE Facilites.AppCo1 = YeildDB.FIPS) AS Expr1
FROM Facilities
The goal is that the sub query should use the value from Facilities.AppCo1 to match with the value in YeildDB.FIPS and then return the corresponding value in YeildDB.CornYeild.
Currently I get a prompt asking for the YeildDB.FIPS value instead of the sub query using the outer query value.
Your code should work. But you can also express this using a LEFT JOIN:
SELECT Facilities.CustomerName, Facilities.FacilityName,
Facilities.AnnualPlan, Facilities.AppCo1,
YeildDB.CornYield
FROM Facilities LEFT JOIN
YeildDB
ON Facilties.AppCo1 = YeildDB.FIPS;
I noticed that you misspelled Facilities -- and that is probably why your version doesn't work. This is one reason to use table aliases:
SELECT f.CustomerName, f.FacilityName,
f.AnnualPlan, f.AppCo1,
y.CornYield
FROM Facilities as f LEFT JOIN
YeildDB as y
ON f.AppCo1 = y.FIPS;
Your sub query may be returning multiple values, hence the prompt asking you to specify which one you want. You can fix this (or at least hide this issue) by specifying top 1:
SELECT Facilities.CustomerName, Facilities.FacilityName,
Facilities.AnnualPlan, Facilities.AppCo1,
(SELECT TOP 1 YeildDB.CornYield
FROM YeildDB
WHERE Facilites.AppCo1 = YeildDB.FIPS) AS Expr1
FROM Facilities

LINQ Joins on nullable column

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

how to join multiple tables without showing repeated data?

I pop into a problem recently, and Im sure its because of how I Join them.
this is my code:
select LP_Pending_Info.Service_Order,
LP_Pending_Info.Pending_Days,
LP_Pending_Info.Service_Type,
LP_Pending_Info.ASC_Code,
LP_Pending_Info.Model,
LP_Pending_Info.IN_OUT_WTY,
LP_Part_Codes.PartCode,
LP_PS_Codes.PS,
LP_Confirmation_Codes.SO_NO,
LP_Pending_Info.Engineer_Code
from LP_Pending_Info
join LP_Part_Codes
on LP_Pending_Info.Service_order = LP_Part_Codes.Service_order
join LP_PS_Codes
on LP_Pending_Info.Service_Order = LP_PS_Codes.Service_Order
join LP_Confirmation_Codes
on LP_Pending_Info.Service_Order = LP_Confirmation_Codes.Service_Order
order by LP_Pending_Info.Service_order, LP_Part_Codes.PartCode;
For every service order I have 5 part code maximum.
If the service order have only one value it show the result correctly but when it have more than one Part code the problem begin.
for example: this service order"4182134076" has only 2 part code, first'GH81-13601A' and second 'GH96-09938A' so it should show the data 2 time but it repeat it for 8 time. what seems to be the problem?
If your records were exactly the same the distinct keyword would have solved it.
However in rows 2 and 3 which have the same Service_Order and Part_Code if you check the SO_NO you see it is different - that is why distinct won't work here - the rows are not identical.
I say you have some problem in one of the conditions in your joins. The different data is in the SO_NO column so check the raw data in the LP_Confirmation_Codes table for that Service_Order:
select * from LP_Confirmation_Codes where Service_Order = 4182134076
I assume you are missing an and with the value from the LP_Part_Codes or LP_PS_Codes (but can't be sure without seeing those tables and data myself).
By this sentence If the service order have only one value it show the result correctly but when it have more than one Part code the problem begin. - probably you are missing and and with the LP_Part_Codes table
Based on your output result, here are the following data that caused multiple output.
Service Order: 4182134076 has :
2 PartCode which are GH81-13601A and GH96-09938A
2 PS which are U and P
2 SO_NO which are 1.00024e+09 and 1.00022e+09
Therefore 2^3 returns 8 rows. I believe that you need to check where you should join your tables.
Use DINTINCT
select distinct LP_Pending_Info.Service_Order,LP_Pending_Info.Pending_Days,
LP_Pending_Info.Service_Type,LP_Pending_Info.ASC_Code,LP_Pending_Info.Model,
LP_Pending_Info.IN_OUT_WTY, LP_Part_Codes.PartCode,LP_PS_Codes.PS,
LP_Confirmation_Codes.SO_NO,LP_Pending_Info.Engineer_Code
from LP_Pending_Info
join LP_Part_Codes on LP_Pending_Info.Service_order = LP_Part_Codes.Service_order
join LP_PS_Codes on LP_Part_Codes.Service_Order = LP_PS_Codes.Service_Order
join LP_Confirmation_Codes on LP_PS_Codes.Service_Order = LP_Confirmation_Codes.Service_Order
order by LP_Pending_Info.Service_order, LP_Part_Codes.PartCode;
distinct will not return duplicates based on your select. So if a row is same, it will only return once.

MS Access SQL Update with Minimum

This SQL is beyond my expertise. I think it should be fairly easy for someone with experience. Here is what I have so far..
SQL is as follows:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)));
I want to add one last condition to this being that I only want the minimum of [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] to update the table. I've tried the obvious of wrapping the field in Min, and also tried creating a separate aggregate select statement first (to get the min value with other criteria) that I then tried to create the update query from in new query but no luck.
I believe this is valid Access/Jet SQL. The idea here is to use a subquery to look up the earliest date among all the rows in your subset. I'm not sure if ms_itn was the right column to correlate on but hopefully you get the idea:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID
SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)))
and [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] = (
select min(sd.[ms_start_date])
from [Tbl_Stg_Project_Schedule_Dates] as sd
where sd.ms_itn = [Tbl_Stg_Project_Schedule_Dates].ms_itn
)

Why do I have to use DISTINCT for this to work?

here's my problem: I have an SQL query that makes 4 calls to a lookup table to return their values from a list of combinations in another table. I finally got this working, and for some reason, when I run the query without DISTINCT, I get a ton of data back, so I'm guessing that I'm either missing something or not doing this correctly. It would be really great if this would not only work, but also return the list alphabetically by the first colour name.
I'm putting my SQL here I hope I've explained this well enough:
SELECT DISTINCT
colour1.ColourID AS colour1_ColourID,
colour1.ColourName AS colour1_ColourName,
colour1.ColourHex AS colour1_ColourHex,
colour1.ManufacturerColourID AS colour1_ManufacturerColourID,
colour2.ColourID AS colour2_ColourID,
colour2.ColourName AS colour2_ColourName,
colour2.ColourHex AS colour2_ColourHex,
colour2.QEColourID2 AS colour2_QEColourID2,
colour3.ColourID AS colour3_ColourID,
colour3.ColourName AS colour3_ColourName,
colour3.ColourHex AS colour3_ColourHex,
colour3.QEColourID3 AS colour3_QEColourID3,
colour4.ColourID AS colour4_ColourID,
colour4.ColourName AS colour4_ColourName,
colour4.ColourHex AS colour4_ColourHex,
colour4.QEColourID4 AS colour4_QEColourID4,
Combinations.ID,
Combinations.ManufacturerColourID AS Combinations_ManufacturerColourID,
Combinations.QEColourID2 AS Combinations_QEColourID2,
Combinations.QEColourID3 AS Combinations_QEColourID3,
Combinations.QEColourID4 AS Combinations_QEColourID4,
Combinations.ColourSupplierID,
ColourSuppliers.ColourSupplier
FROM
ColourSuppliers INNER JOIN
(
colour4 INNER JOIN
(
colour3 INNER JOIN
(
colour2 INNER JOIN
(
colour1 INNER JOIN Combinations ON
colour1.ColourID=Combinations.ManufacturerColourID
) ON colour2.ColourID=Combinations.QEColourID2
) ON colour3.ColourID=Combinations.QEColourID3
) ON colour4.ColourID=Combinations.QEColourID4
) ON ColourSuppliers.ColourSupplierID=Combinations.ColourSupplierID
WHERE Combinations.ColourSupplierID = ?
Thanks
Steph
It looks as though you've probably got multiple records for each set of four colour combinations in the Combinations table - posting the structure of the table might help us to work it out.
Adding the clause order by colour1.ColourName to the end of the query should sort it alphabetically by the first colour name.
My guess (and it is a guess because your SQL query is very wide!) is that you're getting the cartesian product.