The way it looks in the BAQ Designer, you can only check if there are any rows in the entire subquery, there’s no way to link it to the current row being evaluated.
Here’s some sample data to help illustrate the rows that the two queries would return, just from reading the queries.
Part table:
| PartNum | PartDescription |
|---------|-----------------|
| A | Part A |
| B | Part B |
| C | Part C |
PartRev table:
| PartNum | RevisionNum | Approved |
|---------|-------------|----------|
| A | 1 | 1 |
| B | 2 | 0 |
SSMS NOT EXISTS:
SELECT
[P].[PartNum],
[P].[PartDescription]
FROM [Erp].[Part] [P]
WHERE [P].[Company] = 'XXX'
NOT EXISTS (
SELECT
[PR].[Company],
[PR].[PartNum],
[PR].[RevisionNum]
FROM [Erp].[PartRev] [PR]
WHERE [PR].[Company] = [P].[Company] AND
[PR].[PartNum] = [P].[PartNum] AND
[PR].[Approved] = 1
)
BAQ NOT EXISTS (from BAQ Designer General tab):
select
[Part].[PartNum] as [Part_PartNum],
[Part].[PartDescription] as [Part_PartDescription]
from Erp.Part as Part
where (not exists (select
[PartRev].[Company] as [PartRev_Company],
[PartRev].[PartNum] as [PartRev_PartNum],
[PartRev].[RevisionNum] as [PartRev_RevisionNum]
from Erp.PartRev as PartRev
where (PartRev.Approved = 1)))
BAQ NOT EXISTS (from SQL Profiler (reformatted)):
SELECT
[Part].[PartNum] [Part_PartNum],
[Part].[PartDescription] [Part_PartDescription]
FROM [Erp].[Part]
WHERE NOT (
EXISTS (
SELECT
1
FROM (
SELECT
[PartRev].[Company] [PartRev_Company],
[PartRev].[PartNum] [PartRev_PartNum],
[PartRev].[RevisionNum] [PartRev_RevisionNum]
FROM [Erp].[PartRev]
WHERE
([PartRev].[Approved] = 1 AND
(
[PartRev].[Company] IS NULL OR
[PartRev].[Company] = N'' OR
[PartRev].[Company] = @CurrentCompany)
) AND
(
[PartRev].[Plant] IS NULL OR
EXISTS (
SELECT
1 [c1]
FROM [Ice].[SysUserComp] [SysUserComp]
WHERE [SysUserComp].[Company] = [PartRev].[Company] AND
[SysUserComp].[UserID] = @CurrentUserID AND
Ice.lookup(PartRev.Plant, SysUserComp.PlantList, '~') > 0
)
)
) ApprovedPartRevs
)
) AND
(
[Part].[Company] IS NULL OR
[Part].[Company] = N'' OR
[Part].[Company] = @CurrentCompany
)
Evaluations:
| PartNum | PartDescription | RevisionNum | Approved | SSMS NOT EXISTS Row Returned | BAQ NOT EXISTS Row Returned |
|---------|-----------------|-------------|----------|------------------------------|-----------------------------|
| A | Part A | 1 | 1 | FALSE | FALSE |
| B | Part B | 2 | 0 | TRUE | FALSE |
| C | Part C | NULL | NULL | TRUE | FALSE |
With the BAQ (not) EXISTS subquery operation, it doesn’t return any rows because Part A has an Approved revision, whereas the intention was to return Part B and Part C because they don’t have any approved revisions.
It seems like this is just how EXISTS works in BAQs, but I was hoping that I was using it wrong and somebody has an example of using it correctly. I can usually get the results I want using a LEFT JOIN and checking if a column IS NULL and sometimes using DISTINCT in the subquery, but there are times when using EXISTS would be the better solution.