Adding a WHERE clause to a Group Join - vb.net

I am working in VB.NET. I have two datatables (table & table2), which are identical. The two columns in question are:
id | voided_id
1 | null
2 | null
3 | 2
table1 is the list of items, and table2 is the list of voided items. so, if an item has voided an earlier item, I want to exclude the voided item. In this example id 2 would be excluded because it was voided by id 3.
Here is what I have so far:
Dim compareResults = From table In resultOds
Group Join table2 In voidOds
On table.Field(Of Int64)("id") Equals table2.Field(Of Int64?)("voided_loan_id")
Into tablesJoin = Group From tableJoin In tablesJoin.Where(Function(x) x.Field(Of Int64?)("voided_loan_id") Is Nothing).DefaultIfEmpty()
Select table
right now, I get everything. The WHERE clause inside the group join isn't working. Any suggestions?
Many articles I found said .DefaultIfEmpty() should provide the functionality of the WHERE but this returns everything as well:
Dim compareResults2 = From table In resultOds
Group Join table2 In voidOds
On table.Field(Of Int64)("id") Equals table2.Field(Of Int64?)("voided_loan_id") Into tablesJoin = Group
From table2 In tablesJoin.DefaultIfEmpty()
Select table
based on some off-line input I got, I rewrote this as a subquery. Still returns everything.
Dim compareResults2 = From r In resultOds
Where Not (From v In voidOds Where v.Field(Of Int64?)("voided_loan_id") IsNot Nothing Select v.Field(Of Int64?)("voided_loan_id")).Contains(r.Field(Of Int64?)("id"))
Select r

Try below
C#
var s =ItemTable.Where(i=>!VoidedItem.Any(v=>v.id==i.id))?.ToList();
VB
Dim s = ItemTable.Where(Function(i) Not VoidedItem.Any(Function(v) v.id = i.id))?.ToList()

I didn't get it working so I defaulted to executing a SQL string. thanks for the feedback.

Related

Is hiding all rows of duplicated data possible?

I am building a report using a SQL Stored Parameter that I created. It pulls data that may have 1 line per unique number, or 2 lines per unique number. I want to only show rows where there is only 1 line.
I have tried changing visibility, but the closest I have come to is
=IIF(Fields!uniquenumber.Value = previous(Fields!uniquenumber.value,True,False)
but this hides 1 of the rows, and not both. I have also tried using CASE WHEN in the query to identify if there are more than 1 line, but I still haven't been able to hide when there is more than 1 line. My query is below (redacted quite a few lines of extra criteria that aren't relevant to my question here. There are quite a few instances where the first part of my WHERE statement will have data that also meets the criteria of the 2nd part.
SELECT
Reorders.LastRxNo,
Reorders_1.LastRxNo AS Reorders1LastRxNo,
Rxs_2.RxBatch AS Rxs2RxBatch,
Reorders.FacID,
KeyIdentifiers.GPI,
Reorders.LastFillDt,
Rxs_1.RxBatch as Rxs1RxBatch,
CASE
WHEN (Reorders.LastRxNo<>Reorders_1.LastRxNo) THEN 1
ELSE 0
END AS Duplicate
FROM Reorders
LEFT OUTER JOIN Rxs AS Rxs_1
ON Reorders.LastRXNo = Rxs_1.RxNo
RIGHT OUTER JOIN KeyIdentifiers
ON Reorders.NDC = KeyIdentifiers.NDC
INNER JOIN Patients
ON Reorders.FacID = Patients.FacID
AND Reorders.PatID = Patients.PatID
LEFT OUTER JOIN Reorders AS Reorders_1
ON Reorders.FacID = Reorders_1.FacID
AND Reorders.PatID = Reorders_1.PatID
AND KeyIdentifiers.NDC = Reorders_1.NDC
LEFT OUTER JOIN Rxs AS Rxs_2
ON Reorders_1.LastRxNo = Rxs_2.RxNo
WHERE
Reorders.ProfileOnly = 1
AND Rxs_1.RxBatch IS NULL
AND Reorders.CutOffDt IS NULL
AND Reorders.PackType LIKE 'PHDEF%'
AND Reorders.Auto = 1
AND Reorders.PhRxStatus IS NULL
AND Reorders.LastFillDt > '01/01/2019'
AND (Reorders.LastRxNo = Reorders_1.LastRxNo
OR Reorders.LastRxNo <> Reorders_1.LastRxNo AND Rxs_2.RxBatch IN ('CF','GONE'))
ORDER BY Reorders.FacID, Patients.PatLName, Patients.PatFName
Yields Results Similar to:
LastRxNo Reorders1LastRxNo Rxs2RxBatch Duplicate
111 111 null 0
222 222 null 0
222 444 CF 1
In the above example, I only need to see the lines like line 1. Since "LastRxNo" 222 has 2 lines, I do not want to see it on my final report. (However, it is queried, because when LastRxNo =222 AND Reorders1LastRxNo = 222 and Rxs2RxBatch IS NULL would pull if I didn't account for it in my WHERE statement, I think. I am happy doing this any way possible, whether it be in the query or in SSRS report.
Replace your CASE ... as duplicate with
COUNT(*) OVER(PARTITION BY LastRxNo) AS LastRxNoCount
then
wrap the whole query in another select like this...
SELECT * FROM
(
your original query here including the change stated above
) q
WHERE q.LastRxNoCount =1
Just filter out all rows where the number of rows is greater than 1:
SELECT LastRxNo, RxBatch
FROM Reorders
WHERE RxBatch IN ('CF','GONE')
AND Reorders.LastRxNo IN
(SELECT LastRxNo FROM Reorders GROUP BY LastRxNo HAVING COUNT(LastRxNo) = 1)
You should just be able to add the last two lines into your WHERE clause.
Alternatively, you could add it to your JOIN conditions:
SELECT
Reorders.LastRxNo
FROM Reorders
INNER JOIN (
SELECT LastRxNo FROM Reorders
GROUP BY LastRxNo
HAVING COUNT(LastRxNo) = 1
) AS UniqueRxNo ON UniqueRxNo.LastRxNo = Reorders.LastRxNo
Yes, you can do it one of 2 ways:
is in your data source, do a distinct select.
Set the "Hide Duplicates" property on the detail line in the report properties

MS Access SQL left join giving all 0

I am trying to make a summary table of all the items I have. I have a raw data table with 10 users who respectively have different items. There are maximum 3 different items and I want to do a count to see how many items each individual has. The following is my code.
Select b.Country,b.UserID,Num_including_fruits, Apple,Orange
from
(((SELECT o.Country,o.UserID, IIF(ISNULL(Count(o.UserID)),0,Count(o.UserID))
AS Num_including_fruits
FROM [SEA2_View] as o
GROUP BY o.UserID, o.Country
ORDER BY Country)as b
LEFT JOIN
(SELECT o.Country,o.UserID,IIF(ISNULL(Count(o.UserID)),0,Count(o.UserID)
AS Apple
FROM [APAC2_View] as o
WHERE o.fruit_status <>"fresh" AND o.HWType = "Apple"
GROUP BY o.Country,o.UserID)as d
ON (b.UserID = d.UserID))
LEFT JOIN
(SELECT o.Country,o.UserID,IIF(ISNULL(Count(o.UserID)),0,Count(o.UserID))
AS Orange
FROM [SEA2_View] as o
WHERE o.fruit_status <>"fresh" AND o.HWType = "Orange"
GROUP BY o.Country,o.UserID)as e
ON (d.UserID = e.UserID))
;
The first join returns the correct result but the second join somehow returns all 0, which is incorrect. Therefore please help! and I would appreciate any advice for best practice when it comes to joins in SQL. Thanks lot!
Are you sure you don't have a table naming error?
You're first joining [SEA2_View] with [APAC2_View]. The second join is joining with [SEA2_View] with itself.

Update 1 field in a table from another field in a different table (OS400, not a 1 to 1 relationship)

Im trying to update a field in a table from another field in a different table.
The table being updated will have multiple records that need updating from 1 match in the other table.
Example, i have a 1 million row sales history file. Those million records have aproximately 40,000 different sku codes, each row has a date and time stamp. Each sku will have multiple records in there.
I added a new field called MATCOST (material cost).
I have a second table containing SKU and the MATCOST.
So i want to stamp every line in table 1 with the corresponding SKU's MATCOST in table2. I cannot seem to achieve this when its not a 1 to 1 relationship.
This is what i have tried:
update
aulsprx3/cogtest2
set
matcost = (select Matcost from queryfiles/coskitscog where
aulsprx3/cogtest2.item99 = queryfiles/coskitscog.ITEM )
where
aulsprx3/cogtest2.item99=queryfiles/coskitscog.ITEM
But that results in the SQL error: Column qualifier or table COSKITSCOG undefined and highlighting the q in the last reference to queryfiles/coskitscog.Item
Any idea's ?
Kindest Regards
Adam
Update: This is what my tables look like in principle. 1 Table contains the sales data, the other contains the MATCOSTS for the items that were sold. I need to update the Sales Data table (COGTEST2) with the data from the COSKITCOG table. I cannot use a coalesce statement because its not a 1 to 1 relationship, most select functions i use result in the error of multiple selects. The only matching field is Item=Item99
I cant find a way of matching multiple's. In the example we would have to use 3 SQL statements and just specify the item code. But in live i have about 40,000 item codes and over a million sales data records to update. If SQL wont do it, i suppose i'd have to try write it in an RPG program but thats way beyond me for the moment.
Thanks for any help you can provide.
Ok this is the final SQL statement that worked. (there were actually 3 values to update)
UPDATE atst2f2/SAP20 ct
SET VAL520 = (SELECT cs.MATCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
VAL620 = (SELECT cs.LABCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
VAL720 = (SELECT cs.OVRCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
WHERE ct.pnum20 IN (SELECT cs.ITEM
FROM queryfiles/coskitscog cs)
This more compact way to do the same thing should be more efficient, eh?
UPDATE atst2f2/SAP20 ct
SET (VAL520, VAL620, VAL720) =
(SELECT cs.MATCOST, cs.LABCOST, cs.OVRCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20)
WHERE ct.pnum20 IN (SELECT cs.ITEM
FROM queryfiles/coskitscog cs)
Qualify the columns with correlation names.
UPDATE AULSPRX3/COGTEST2 A
SET A.matcost = (SELECT matcost
FROM QUERYFILES/COSKITSCOG B
WHERE A.item99 = B.item)
WHERE EXISTS(SELECT *
FROM QUERYFILES/COSKITSCOG C
WHERE A.item99 = C.item)
From UPDATE, I'd suggest:
update
aulsprx3/cogtest2
set
(matcost) = (select Matcost from queryfiles/coskitscog where
aulsprx3/cogtest2.item99 = queryfiles/coskitscog.ITEM)
where
aulsprx3/cogtest2.item99=queryfiles/coskitscog.ITEM
Note the braces around matcost.

Different results on the basis of different foreign key value using a falg in where clause

Please see attached image.
alt text http://img241.imageshack.us/img241/3585/customcost.png
Can you please tell me what query will work. Please ignore isdefinite and productpriceid columns.
Thanks
If you want a single query, this should do it if I've interpreted your question properly:
SELECT DISTINCT t1.SupplierVenueProductID, [...]
FROM table t1
LEFT JOIN
table t2
ON t1.SupplierVenueProductID = t2.SupplierVenueProductID
AND t2.iscustomcost = 1
WHERE t2.SupplierVenueProductID IS NULL
OR t1.iscustomcost = 1
I don't know your table name, but you join it to itself.
I'm a bit lost on what you want to accomplish here,
going by your requirement if isCustomCost = 1 then return record #3 from SupplierVenueProductId 1 and both records from SupplierVenueProductId 2
Trying to generalize this, I think what you need is :
return all rows from the table, unless when there is a record for a SupplierVenueProductId that has isCustomCost = 1, then only return that record for this SupplierVenueProductId
Which then becomes something along the lines of :
SELECT t1.*
FROM myTable t1
WHERE t1.isCustomCost = 1
OR NOT EXISTs (SELECT *
FROM t2
WHERE t2.SupplierVenueProductId = t1.SupplierVenueProductId
AND t2.isCustomCost = 1)
Hope this helps.

outer query to list only if its rowcount equates to inner subquery

Need help on a query using sql server 2005
I am having two tables
code
chargecode
chargeid
orgid
entry
chargeid
itemNo
rate
I need to list all the chargeids in entry table if it contains multiple entries having different chargeids
which got listed in code table having the same charge code.
data :
code
100,1,100
100,2,100
100,3,100
101,11,100
101,12,100
entry
1,x1,1
1,x2,2
2,x3,2
11,x4,1
11,x5,1
using the above data , it query should list chargeids 1 and 2 and not 11.
I got the way to know how many rows in entry satisfies the criteria, but m failing to get the chargeids
select count (distinct chargeId)
from entry where chargeid in (select chargeid from code where chargecode = (SELECT A.chargecode
from code as A join code as B
ON A.chargecode = B.chargeCode and A.chargetype = B.chargetype and A.orgId = B.orgId AND A.CHARGEID = b.CHARGEid
group by A.chargecode,A.orgid
having count(A.chargecode) > 1)
)
First off: I apologise for my completely inaccurate original answer.
The solution to your problem is a self-join. Self-joins are used when you want to select more than one row from the same table. In our case we want to select two charge IDs that have the same charge code:
SELECT DISTINCT c1.chargeid, c2.chargeid FROM code c1
JOIN code c2 ON c1.chargeid != c2.chargeid AND c1.chargecode = c2.chargecode
JOIN entry e1 ON e1.chargeid = c1.chargeid
JOIN entry e2 ON e2.chargeid = c2.chargeid
WHERE c1.chargeid < c2.chargeid
Explanation of this:
First we pick any two charge IDs from 'code'. The DISTINCT avoids duplicates. We make sure they're two different IDs and that they map to the same chargecode.
Then we join on 'entry' (twice) to make sure they both appear in the entry table.
This approach gives (for your example) the pairs (1,2) and (2,1). So we also insist on an ordering; this cuts to result set down to just (1,2), as you described.