Execute a select from two tables with same columns - sql

I have two tables with same columns, I need to make a select in this two tables, I want to know how is the best way to make this, my select test is:
SELECT
ISNULL(LoteDet.IdLoteDet, LoteDetPg.IdLoteDet) AS Expr1,
ISNULL(LoteDet.IDSac, LoteDetPg.IDSac) AS Expr2,
ISNULL(LoteDet.Comprom, LoteDetPg.Comprom) AS Expr3,
ISNULL(LoteDet.NossoNum, LoteDetPg.NossoNum) AS Expr4,
ISNULL(LoteDet.NossoNumDig, LoteDetPg.NossoNumDig) AS Expr5
FROM
LoteDet
CROSS JOIN
LoteDetPg
WHERE
Expr1 = 500
It's possible to make this ?
How is the better way to execute this kind of select, if not found the value in one table, the value will be in the other table....
------ EDIT
Perhaps create a view is a good alternative to this type of select?

Use COALESCE:
SELECT
COALESCE(LoteDet.IdLoteDet, LoteDetPg.IdLoteDet) AS Expr1,
COALESCE(LoteDet.IDSac, LoteDetPg.IDSac) AS Expr2,
COALESCE(LoteDet.Comprom, LoteDetPg.Comprom) AS Expr3,
COALESCE(LoteDet.NossoNum, LoteDetPg.NossoNum) AS Expr4,
COALESCE(LoteDet.NossoNumDig, LoteDetPg.NossoNumDig) AS Expr5
FROM
LoteDet
CROSS JOIN
LoteDetPg
WHERE
Expr1 = 500
Take a look on this documentation: https://msdn.microsoft.com/pt-br/library/ms190349.aspx

I believe this is going to return you what's called a Cartesian Product. It's the result of an open join, like you have above. That query is going to return TONS of records because you're not specifying how to JOIN the two tables, it's just going to blindly try matching columns. At the very least, add an ON condition to the JOIN so that you can match on IDs/keys. I think what you want is an INNER JOIN with an ON; this will return you all of the matching rows, based on ID/Key.
SELECT
CASE WHEN tbl1.Comprom IS NULL THEN tbl2.Comprom ELSE tbl1.Comprom END AS Expr1
CASE WHEN tbl1.Nossonum IS NULL THEN tbl2.Nossonum ELSE tbl1.Nossonum END AS Expr2
FROM
tbl1 --LoteDet
INNER JOIN tbl2 --LoteDetPg
ON (tbl1.ID = tbl2.ID)
WHERE
Expr1 = 500 --I know I swapped the expression values, use whichever expression you need here
Now, only rows that have a matching ID will return you values and it will use the value from tbl1, unless it is null, then it will use the value from tbl2.
Edit: I know CROSS JOIN turns into an INNER JOIN if a WHERE is specified, but does the WHERE need to include both tables? I feel that the Expr1 = 500 will still produce a Cartesian Product; can someone correct me?

Related

Getting Duplicate Values When Joining the Same Table Twice

Multiple joins to the same table using different criteria.
I'm trying to get a value from a table but have different criteria. There is a column that has the value I'm trying to retrieve. There are two sets of criteria.
The issue is with the Else line. The logic is, if the conditions in the first join are true, then get the c_wRVUAmt value. If there is no match, then use the conditions from the second join. If there is no match there, then use 0.
I'm getting duplicate records, which I understand. I just don't understand how to write the joins or the query to eliminate duplicate rows.
select a.[Revenue Id]
,a.CPT
,a.[Procedure Mod]
,dd.MemberId
,ee.MemberId
,dd.c_HCPCS
,ee.c_HCPCS
,dd.c_MOD
,ee.c_MOD
,CASE When a.[GL Company Unit] IN ('6500','6600','6700') and a.[Rev Code] = '0320'
then 0
When RTRIM(a.[BE Name]) <> 'Hospital'
Then 0
Else ISNULL(dd.c_wRVUAmt * a.[Total Qty],0)+ISNULL(ee.c_wRVUAmt * a.[Total Qty],0)
end as WorkRVUAmt
from GP_CUSTOMS..Revenue_Staging a
Left Outer Join d_Dim22 dd on a.[CPT] = dd.c_HCPCS
and a.[Procedure Mod] = dd.c_MOD
and a.[Procedure Mod] in ('26','53')
Left Outer Join d_Dim22 ee on a.[CPT] = ee.c_HCPCS
and a.[Procedure Mod] NOT IN ('26','53')
I'm looking for one row.
There are many ways to remove duplicates.
One of these is to select data with a subselect.
Try to put around your select another select WITH DISTINCT:
SELECT DISTINCT
[Revenue Id]
,CPT
,[Procedure Mod]
,MemberId1
,MemberId2
,c_HCPCS
,c_HCPCS
,c_MOD
,c_MOD
,WorkRVUAmt
FROM (<YOUR SELECT HERE>)
Remember to give an alias to your column names MemberId (e.g. MemberId1, MemberId2)
There is no way to eliminate records happen to come out of the left joins provided in your query. You can either write a correlated subquery and pass out a row instead from either of the tables on the right side of the joins or modify the result in the select by distinct which I believe is not your option!

SQL Server Query - Weird Behaviour

Consider below SQL.
SELECT DISTINCT bvc_Order.ID,
bvc_OrderItem.ProductID,
bvc_OrderItem_BundleItem.ProductID
FROM dbo.bvc_OrderItem WITH (nolock)
RIGHT OUTER JOIN dbo.bvc_Order WITH (nolock)
LEFT OUTER JOIN dbo.bvc_User WITH (nolock) ON dbo.bvc_Order.UserID = dbo.bvc_User.ID
LEFT OUTER JOIN dbo.Amazon_Merchants WITH (nolock) ON dbo.bvc_Order.CompanyID = dbo.Amazon_Merchants.ID ON dbo.bvc_OrderItem.OrderID = dbo.bvc_Order.ID
LEFT OUTER JOIN dbo.bvc_OrderItem_BundleItem WITH (nolock) ON dbo.bvc_OrderItem.ID = dbo.bvc_OrderItem_BundleItem.OrderItemID
LEFT OUTER JOIN dbo.bvc_Product WITH (nolock) ON dbo.bvc_OrderItem.ProductID = dbo.bvc_Product.ID
WHERE 1=1
AND (bvc_Order.StatusCode <> 1
AND bvc_Order.StatusCode <> 999)
AND ( bvc_OrderItem.ProductID IN ('28046_00')
OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00'))
AND bvc_Order.OrderSource = 56;
The query when I execute against my database, it returns 85 rows. Well, that is not correct.
If I just remove the part "AND bvc_Order.OrderSource = 56" it returns back 5 rows which is really correct.
Strange.....
Another thing, if I remove the part
OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00')
it will also return the 5 rows as expected even with bvc_Order.OrderSource filter.
I am not sure why it is adding more rows while I am trying to reduce rows by using filters.
the table bvc_OrderItem_BundleItem doesn't contain any rows for the result order ids or OrderItemIDs
[edit]
Thanks guys, I tried to remove the LEFT/RIGHT Join Mix but Query manager doesn't allows only LEFT, it does add at least one RIGHT join. I updated the SQL to remove extra tables and now we have only three. But same result
SELECT DISTINCT dbo.bvc_Order.ID, dbo.bvc_OrderItem.ProductID, dbo.bvc_OrderItem_BundleItem.ProductID AS Expr1
FROM dbo.bvc_OrderItem
LEFT OUTER JOIN dbo.bvc_OrderItem_BundleItem ON dbo.bvc_OrderItem.ID = dbo.bvc_OrderItem_BundleItem.OrderItemId
RIGHT OUTER JOIN dbo.bvc_Order ON dbo.bvc_OrderItem.OrderID = dbo.bvc_Order.ID
WHERE 1=1
AND (bvc_Order.StatusCode <> 1 AND bvc_Order.StatusCode <> 999)
AND (
bvc_OrderItem.ProductID IN ('28046_00')
OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00')
)
AND bvc_Order.OrderSource = 56;
[edit]So far, there is no solution for this. I previously pasted a link in my comment with example data outout for both valid/invalid results with queries. here it is again.
http://sameers.me/SQLIssue.xlsx
One thing to remember here is that ALL left join is not possible. Let me explain further
bvc_Order contains main order record
bvc_ORderItem contains Order Items/Products
bvc_ORderItem_BundleItem contains child products of the product which are available in bvC_OrderItem table.
Now NOT Every product has child products, so bvc_OrderItem_BundleItem may not have any record (and in current scenario, there is really no valid row for the orders in bvC_OrderItem_BundleItem).
In short, in current scenario, there is NO matching row available in bvc_OrderItem_BundleItem table. If I remove that join for now, it is all okay, but in real world, I can't remove that BundleItem table join ofcourse.
thank you
When you say
WHERE bvc_Order.OrderSource = 56
that evaluates to false when bvc_Order.OrderSource is NULL. If the LEFT/RIGHT join failed then it will be NULL. This effectively turns the LEFT/RIGHT join into an inner join.
You probably should write the predicate into the ON clause. An alternative approach, which might not deliver the same results, is:
WHERE (bvc_Order.OrderSource IS NULL OR bvc_Order.OrderSource = 56)
The other predicates have the same problem:
Another thing, if I remove the part OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00') it will also return the 5 rows as expected
When the join fails bvc_OrderItem_BundleItem.ProductID is NULL.
I also would recommend writing queries manually. If I understand you right this query comes from a designer. It's structure is quite confusing. I'm pulling up the most important comment:
Mixing left and right outer joins in a query is just confusing. You should start by rewriting the from clause to only use one type (and I strongly recommend left outer join). – Gordon Linoff
When you have eliminated the impossible, whatever remains, however
improbable, must be the truth? S.H.
It is impossible that an extra AND condition appended to a WHERE clause can ever result in extra rows. That would imply a database engine defect, which I hope I can assume is "impossible". (If not, then I guess it's back to square one).
That fact makes it easier to concentrate on possible reasons:
When you comment out
AND bvc_Order.OrderSource = 56;
then you also comment out the semicolon terminator. Is it possible
that there is text following this query that is affecting it? Try
putting a semicolon at the end of the previous line to make sure.
Depending on the tool you are using to run queries, sometimes when a
query fails to execute, the tool mistakenly shows an old result set.
Make sure your query is executing correctly by adding a dummy column
to the SELECT statement to absolutely prove you are seeing live
results. Which tool are you using?
when you use LEFT outer join it will give all the rows from left table (dbo.bvc_OrderItem) once the your and, or conditions satisfies,
the same thing happens with Right outer join too,
Those conditions (Left join, right join ) may not restrict the rows since rows from one table can be all, another table with some rows only.
check with your join condition
Then check you condition :
(bvc_Order.StatusCode <> 1 AND bvc_Order.StatusCode <> 999)
if any rows satisfying this condition
next check with another condition
[bvc_OrderItem.ProductID IN ('28046_00')
OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00')]
Then bvc_Order.OrderSource = 56
compare the result of three queries and check the data in with the conditions and then write your complete query, so that you will understand where the mistake you have done.
Few points to remember
1.And is applied during Virtual join phases
2.Where clause is applied after the final result
3.Left join followed by right join is effectively an inner join in some cases
Lets break your query step by step..
dbo.bvc_OrderItem a1
LEFT OUTER JOIN
dbo.bvc_OrderItem_BundleItem b1
Above output will be a single virtual table (logically) which contains all rows from b1 with matching rows from a1
now below predicates from your and clause will be applied
bvc_OrderItem.ProductID IN ('28046_00')
OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00')
which effectively eliminates all rows from bvc_OrderItem_BundleItem even if they have matches and gives result some thing like below if bvc_OrderItem_BundleItem.ProductID IN ('28046_00') is true
bvc_OrderItem bvc_OrderItem_BundleItem
28046 28046
null 1
null 2
null 3
if this condition(bvc_OrderItem.ProductID IN ('28046_00')) is true,then you are asking sql to ignore all rows in bvc_OrderItem ,which effectively means the same result set as above
bvc_OrderItem bvc_OrderItem_BundleItem other columns
28046 28046
null 1
null 2
null 3
next you are doing right outer join with dbo.bvc_Order which may qualifies for the join point I mentioned above
Assume ,you got below result set as output which preserves all of bvc_order table(rough output only for understanding due to lack of actual data)
bvc_OrderItem bvc_OrderItem_BundleItem statuscode ordersource
28046 28046 999 56
null 1 1 57
null 2 100 58
null 3 11 59
Next below AND predicates will be applied
status code <>1 and statuscode<> 999
which means ignore rows which match with bvc_order and has status of 1 ,999 even if they found matching rows
Next you are asking bvc_Order.OrderSource = 56; which means I don't care about other rows,preserve matching rows only for 56 and keep the rest as null
Hope this clarifies on what is happening step by step.A more better way can be provide some test data and show the expected output.
you also can control physical order of joins,you can try below to see if this is what you are trying to do..
SELECT DISTINCT dbo.bvc_Order.ID, dbo.bvc_OrderItem.ProductID, dbo.bvc_OrderItem_BundleItem.ProductID AS Expr1
dbo.bvc_OrderItem
LEFT OUTER JOIN
(
dbo.bvc_OrderItem_BundleItem
RIGHT OUTER JOIN
dbo.bvc_Order
ON dbo.bvc_OrderItem.OrderID = dbo.bvc_OrderItem_BundleItem.OrderItemId
)c
on
dbo.bvc_OrderItem.ID = c.bvc_OrderItem_BundleItem.OrderItemId
WHERE 1=1
AND (bvc_Order.StatusCode <> 1 AND bvc_Order.StatusCode <> 999)
AND (
bvc_OrderItem.ProductID IN ('28046_00')
OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00')
)
AND bvc_Order.OrderSource = 56;
It looks like you are using the Query Designer. I would avoid using this as this can make your queries extremely confusing. Your queries will be much more concise if you are designing them by hand. If you don't completely understand how inner/outer joins work, a great textbook that I used to teach myself SQL is Murach's SQL Server for Developers.
https://www.murach.com/shop/murach-s-sql-server-2012-for-developers-detail
Now, onto the answer.
I've been thinking about how to resolve your problem, and if you are trying to reduce the result set to 5 rows, why are you using multiple outer joins in the first place? I would consider switching the joins to inner joins instead of outer joins if you are looking for a very specific result set. I can't really provide you with a really comprehensive answer without looking at exactly what results you are trying to achieve, but here's a general idea based on what you've provided to all of us:
SELECT DISTINCT dbo.bvc_Order.ID, dbo.bvc_OrderItem.ProductID, dbo.bvc_OrderItem_BundleItem.ProductID AS 'bvc_OrderItem_BundleItem_ProductID'
FROM dbo.bvc_OrderItem
INNER JOIN dbo.bvc_OrderItem_BundleItem ON dbo.bvc_OrderItem.ID = dbo.bvc_OrderItem_BundleItem.OrderItemId
INNER JOIN dbo.bvc_Order ON dbo.bvc_OrderItem.OrderID = dbo.bvc_Order.ID
Start here and then based upon what you are searching for, add where clauses to filter criteria.
Also, your where clause must be rewritten if you use an inner join instead of an outer join:
WHERE 1=1 --not really sure why this is here. This will always be true. Omit this statement to avoid a bad result set.
AND (bvc_Order.StatusCode <> 1 AND bvc_Order.StatusCode <> 999) --this is saying, if the StatusCode is not equal to 1 and not equal to 999, don't include it.
--Revised: Look for Status codes with 1 or 999
--bvc_Order.StatusCode = 1 OR bvc_Order.StatusCode = 999
AND (bvc_OrderItem.ProductID IN ('28046_00') --I would eliminate this unless you are looking to see if this exists in Product ID. You could also accomplish this if you are trying to see if this value is in both tables, change this to:
bvc_OrderItem.ProductID = '28046_00' AND bvc_OrderItem_BundleItem.ProductID = '28046_00')
--if you are trying to see if the order source is 56, use this.
AND bvc_Order.OrderSource = 56;
If you are trying to find out rows that are not included in this result set, then I would use OUTER JOIN as necessary (LEFT preferred). Without more information about what you're looking for in your database, that's the best all of us can do.
bLike #usr writ, the reason of this unexpected (for you) result is, you build query with outer joins, and filter rows after join. If you need filter rows of outer joined tables, you should do this before join.
but probably you try build this:
SELECT DISTINCT o.ID, oi.ProductID, bi.ProductID AS Expr1
FROM dbo.bvc_Order as o
LEFT JOIN dbo.bvc_OrderItem as oi on oi.OrderID = o.ID
LEFT JOIN dbo.bvc_OrderItem_BundleItem as bi ON oi.ID = bi.OrderItemId
WHERE 1=1
AND o.OrderSource = 56;
AND o.StatusCode not in (1, 999)
AND '28046_00' in (oi.ProductID, isnull(bi.ProductID,'_') )
Is this query give results what you need?
if not, try change last condition, for example:
and (bi.ProductID = '28046_00' or bi.ProductID is null and oi.ProductID = '28046_00')
you can also put additional condition in to join conditions, for example:
SELECT DISTINCT o.ID, oi.ProductID, bi.ProductID AS Expr1
FROM dbo.bvc_Order as o
LEFT JOIN dbo.bvc_OrderItem as oi on oi.OrderID = o.ID
LEFT JOIN dbo.bvc_OrderItem_BundleItem as bi ON oi.ID = bi.OrderItemId
and bi.ProductID in ('28046_00') --this join BundleItem only if ...
WHERE 1=1
AND o.OrderSource = 56;
AND o.StatusCode not in (1, 999)
AND (oi.ProductID in ('28046_00') or bi.ProductID is not null)
ah, and if you always need join bvc_Order with bvc_OrderItem then use inner join

Selecting NVL With Joins

I am trying to write an SQL statement that will pull the value from one table and its corresponding value from another. This works fine unless one of the values that are being used in a join are null, then it returns nothing. I would like the script to return a value (like 'Nothing') in the event the join is null. Is this possible? I know I can use NVL in the select but what about the join? Here is my script:
SELECT
i.equip_pk,
i.request_pk,
MY_ALIAS.EQUIP_ALIAS_ID
FROM
tableOne i
JOIN table2 MY_ALIAS ON (i.EQUIP_PK = MY_ALIAS.EQUIP_PK)
WHERE i.request_pk=:requestPk
I am using Oracle 10g but this script is not going to be used as PL/SQL.
Thanks for any help
jason
You can use a LEFT JOIN. That will return all rows from tableOne, and when it can't find a match in the second table, it will return null. Then you can use NVL like you mentioned.
SELECT
i.equip_pk,
i.request_pk,
NVL(MY_ALIAS.EQUIP_ALIAS_ID, 'Nothing here')
FROM tableOne i
LEFT OUTER JOIN table2 MY_ALIAS ON (i.EQUIP_PK = MY_ALIAS.EQUIP_PK)
WHERE i.request_pk=:requestPk
If you're expecting nulls from equip_pk, you can apply NVL to that to. Even if it's null, the LEFT JOIN will still produce the proper result.
SELECT
NVL(i.equip_pk, 'Nothing'),
NVL(i.request_pk, 'Nothing)',
MY_ALIAS.EQUIP_ALIAS_ID
FROM
tableOne i
FULL JOIN table2 MY_ALIAS ON (i.EQUIP_PK = MY_ALIAS.EQUIP_PK)
WHERE i.request_pk=:requestPk

Conditional JOIN

I'm wondering if it's possible to accomplish this in MS Access 2007:
A client gave me several tables, and they asked me for some queries. One of them has to get a field value from a table, depending on the value of a field of each record. This means, depending on the region, it has to look at one table, a second, or a third one.
So, I was wondering if I could do something like this:
SELECT
table2.some_value
FROM
table1
INNER JOIN table2
ON CASE table1.SOME_VALUE THEN table3.id = table2.some_id ELSE
CASE table1.SOME_VALUE THEN table4.id = table2.some_id ELSE
table5.id = table2.some_id END END
Is it clear? IF not, just ask and I'll answer your doubts.
EDIT:
I think I was not clear enough. I have a several joins in my query, but I have this last one, in which its ON statement will be different, depending on the data. For example:
I have a record in a table that has a State field, with three possibilities: CA, TX, FL.
If the value is CA, the ON statement of that JOIN should be CA_Standard_table.field = myTable.field.
If it's TX, the ON statement of that JOIN should be TX_Standard_table.field = myTable.field
And the same logic goes for FL.
How can I accomplish that?
EDIT 2:
Here is the query code, the last JOIN is the one that matters for this. The three possibilities of tables to join with in the ON statement are:
EU_Accepted_Standards
CA_Accepted_Standards
NZ_Accepted_Standards
It will decide for one of them, depending of which of the following fields are checked:
CAStandard: it should take CA_Accepted_Standards.
EUSelStandard:it should take EU_Accepted_Standards.
NZ_Accepted_Standards: it should take NZ_Accepted_Standards
Query
SELECT
Projects.COMPAS_ID,
Projects.[Opportunity Name],
IIf([VolCap]=True,1) AS [Volume Cap],
IIf([DelGuarantee]=True,1) AS [Delivery Guarantee],
Projects.Tech_Level_Name,
Counterparty.CPExpertise,
Counterparty.CPFinStrength,
Geographic_Location.Country_RiskLevel,
Project_Stage_Risk.ProStaRiskLevel,
Counterparty.CPExperience,
Projects.Country_Name,
IIf([EU ETS]=True,1) AS EU,
IIf([CA ETS]=True,1) AS CA,
IIf([NZ ETS]=True,1) AS NZ,
IIf([Australia ETS]=True,1) AS Australia,
IIf([CAProjectType] is not null, CA_Accepted_Projects.CAPTRiskLevel,
IIf([EUSelProjType] is not null, EU_ETS_Standards.EUPTRiskLevel,
IIf([NZSelProjType] is not null, NZ_Accepted_Projects.NZPTRiskLevel))) as [Risk Level],
IIf([CAStandard] is not null, CA_Accepted_Standards.CAStanRiskLevel,
IIf([EUSelStandard] is not null, EU_Accepted_Standards.EUStanRiskLevel,
IIf([NZSelStandard] is not null, NZ_Accepted_Standards.NZStanRiskLevel))) as [Standard Risk]
FROM
Project_Stage_Risk
INNER JOIN (((((((((Counterparty
INNER JOIN Projects
ON Counterparty.CPID = Projects.[Counter Party])
INNER JOIN Geographic_Location
ON Projects.Country_Name = Geographic_Location.Country_Name)
left JOIN CA_Accepted_Projects
ON Projects.CAProjectType = CA_Accepted_Projects.CA_ProjectTypes)
left JOIN NZ_Accepted_Projects
ON Projects.NZSelProjType = NZ_Accepted_Projects.NZ_StandardID)
left JOIN EU_ETS_Standards
ON Projects.EUSelProjType = EU_ETS_Standards.EU_StandardID)
left JOIN CA_Accepted_Standards
ON Projects.CAStandard = CA_Accepted_Standards.ID)
left JOIN NZ_Accepted_Standards
ON Projects.NZSelStandard = NZ_Accepted_Standards.ID)
left JOIN EU_Accepted_Standards
ON Projects.EUSelStandard = EU_Accepted_Standards.ID)
left join Emissions_Trading_Systems
ON Emissions_Trading_Systems.ETS = EU_Accepted_Standards.ETS)
ON Project_Stage_Risk.ProStaID = Projects.[Project Stage];
cross join the two sets in a view, put the condition in the select. make 2 views of this view. Join the 2 views together.
You could create a UNION query that unions together the three tables you want to conditionally join to, including a "Some_Value" column that will contain the item on which you want to join. Essentially, for each table you include in the UNION, set the value of the "Some_Value" column to a value you can use in a where clause to differentiate things. Then create an overall query that joins (in your example, table2) to the union query and use a WHERE clause to limit the records to the ones you need. I have done similar things myself on projects in the past with great success.
Thanks for the answers. I know it was not well explained though, but in the end, I could solve this problem by writing a subquery.
Join all five tables together, and use that CASE expression inside the SELECT clause to choose the appropriate field from all tables.
SELECT
CASE table1.some_value
WHEN 'a' THEN table2.some_value
WHEN 'b' THEN table3.some_value
WHEN 'c' THEN table4.some_value
WHEN 'd' THEN table5.some_value
END

How can I exclude values from a third query (Access)

I have a query that shows me a listing of ALL opportunities in one query
I have a query that shows me a listing of EXCLUSION opportunities, ones we want to eliminate from the results
I need to produce a query that will take everything from the first query minus the second query...
SELECT DISTINCT qryMissedOpportunity_ALL_Clients.*
FROM qryMissedOpportunity_ALL_Clients INNER JOIN qryMissedOpportunity_Exclusions ON
([qryMissedOpportunity_ALL_Clients].[ClientID] <> [qryMissedOpportunity_Exclusions].[ClientID])
AND
([qryMissedOpportunity_Exclusions].[ClientID] <> [qryMissedOpportunity_Exclusions].[BillingCode])
The initial query works as intended and exclusions successfully lists all the hits, but I get the full listing when I query with the above which is obviously wrong. Any tips would be appreciated.
EDIT - Two originating queries
qryMissedOpportunity_ALL_Clients (1)
SELECT MissedOpportunities.MOID, PriceList.BillingCode, Client.ClientID, Client.ClientName, PriceList.WorkDescription, PriceList.UnitOfWork, MissedOpportunities.Qty, PriceList.CostPerUnit AS Our_PriceList_Cost, ([MissedOpportunities].[Qty]*[PriceList].[CostPerUnit]) AS At_Cost, MissedOpportunities.fBegin
FROM PriceList INNER JOIN (Client INNER JOIN MissedOpportunities ON Client.ClientID = MissedOpportunities.ClientID) ON PriceList.BillingCode = MissedOpportunities.BillingCode
WHERE (((MissedOpportunities.fBegin)=#10/1/2009#));
qryMissedOpportunity_Exclusions
SELECT qryMissedOpportunity_ALL_Clients.*, MissedOpportunity_Exclusions.Exclusion, MissedOpportunity_Exclusions.Comments
FROM qryMissedOpportunity_ALL_Clients INNER JOIN MissedOpportunity_Exclusions ON (qryMissedOpportunity_ALL_Clients.BillingCode = MissedOpportunity_Exclusions.BillingCode) AND (qryMissedOpportunity_ALL_Clients.ClientID = MissedOpportunity_Exclusions.ClientID)
WHERE (((MissedOpportunity_Exclusions.Exclusion)=True));
One group needs to see everything, the other needs to see things they havn't deamed as "valid" missed opportunity as in, we've seen it, verified why its there and don't need to bother critiquing it every single month.
Generally you can exclude a table by doing a left join and comparing against null:
SELECT t1.* FROM t1 LEFT JOIN t2 on t1.id = t2.id where t2.id is null;
Should be pretty easy to adopt this to your situation.
Looking at your query rewritten to use table aliases so I can read it...
SELECT DISTINCT c.*
FROM qryMissedOpportunity_ALL_Clients c
JOIN qryMissedOpportunity_Exclusions e
ON c.ClientID <> e.ClientID
AND e.ClientID <> e.BillingCode
This query will produce a cartesian product of sorts... each and every row in qryMissedOpportunity_ALL_Clients will match and join with every row in qryMissedOpportunity_Exclusions where ClientIDs do not match... Is this what you want?? Generally join conditions are based on a column in one table being equal to the value of a column in the other table... Joining where they are not equal is unusual ...
Second, the second iniquality in the join conditions is between columns in the same table (qryMissedOpportunity_Exclusions table) Are you sure this is what you want? If it is, it is not a join condition, it is a Where clause condition...
Second, your question mentions two queries, but there is only the one query (above) in yr question. Where is the second one?