You are sort of correct that the solution will require two stages. However,
that does not translate into two trips to the database. There is a special
type of JOIN that is relevant for this task: the outer join. Since you are
using Access, you should look it up in online help since this example will
only utilize one aspect of this type of join.
This example will also utilize a "derived" or "virtual" table, which is
defined as a table, a set of rows, derived as the result of a select
statement. The derived table can be used in the FROM clause of another
query. There are two ways this can be accomplished. The first that I will
demonstrate utilizes a saved query created using the Access Query Builder.
Open your database in Access and switch to the Queries tab. Then
double-click the item in the window that says "Create New Query in Design
View". Close the Choose Tables dialog without selecting a table, switch to
SQL View and paste this sql statement into the window:
SELECT GroupID FROM
tblGroupsContacts
WHERE ContactID = [pContactID]
Run the query, entering 1 when you are prompted for a value for
[pContactID]. You should see a list of GroupIDs to which ContactID 1
belongs. Click the Save toolbar button (or do File|Save from the menu) and
save this query as "qGroupsForSpecifiedID".
Now create another query in Design View, again switching to SQL View without
selecting any tables and paste this sql statement in:
SELECT g.GroupID, GroupName
FROM tblGroups As g LEFT OUTER JOIN
qGroupsForSpecifiedIDAs q
ON g.GroupID = q.GroupID
WHERE q.GroupID Is Null
Run this query, again supplying 1 when prompted. You should see your desired
result.
The other way to do this is to use a subquery, like this (assumes Access
2000 or later):
SELECT g.GroupID, GroupName
FROM tblGroups As g LEFT OUTER JOIN
(SELECT GroupID FROM
tblGroupsContacts
WHERE ContactID = [pContactID]) As q
ON g.GroupID = q.GroupID
WHERE q.GroupID Is Null
Which version should you use? Well, it depends on whether or not you intend
to re-use the sql used in the subquery. If this is the only place it will be
needed, then use the second (subquery) version. If you see other
applications for the sql in the subquery, then you should put it in the
saved query so it can be reused whenever you need it for other queries,
without having to rewrite it.
In either case, you should save the final version as
"qGroupsNotJoinedBySpecifiedContact" so you can call it from ASP like this:
contactid = clng(1)
Set rs=createobject("adodb.recordset")
conn.qGroupsNotJoinedBySpecifiedContact contactid , rs
If not rs.EOF then
'process the array - I recommend using GetRows*
else
'no records were returned
end if
Here is more information about using this technique to run saved parameter
queries from asp:
http://groups-beta.google.com/group/microsoft.public.inetserver.asp.db/msg/b3d322b882a604bd
http://www.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=e6lLVvOcDHA.1204%40TK2MSFTNGP12.phx.gbl
and this illustrates why I recommend using saved parameter queries instead
of dynamic sql:
http://mvp.unixwiz.net/techtips/sql-injection.html http://www.sqlsecurity.com/DesktopDefault.aspx?tabid=23 OK, I've shown you how to achieve your specific requirement: "I want my sql
to find (for a particular ContactID)the group names of
the groups they are not a member of. ie Hockey and Netball"
Hopefully you'll be able to build on this to retrieve other data you need
for your page without making multiple trips to your database.
Bob Barrows
*Should I use recordset iteration, or GetRows(), or GetString()?
http://www.aspfaq.com/show.asp?id=2467 [quoted text, click to view] iam247@gmail.com wrote:
> Hi Bob
>
> Thanks for the offer to build a suitable SQL statement for me.
>
> Here are the details
>
> Database MS Access 2002
>
>
> tblContacts
> ContactID Lng Integer - example data = 1,2,3,67,88,99
> (Other fields not relevant)
>
> tblGroups
> GroupID Lng Integer - data = 1,2,3,4,5
> GroupName Text - matching data = Football, Rugby, Cricket, Hockey,
> Netball
>
> tblGroupContact
> ContactID Lng Integer - example data = 1,1,1,2,67
> GroupID Lng Integer - data = 1,2,3,2,5
>
> ie from the above, ContactID 1 is a member of groups 1,2 & 3 but not
> groups 4 & 5.
> **************
> I want my sql to find (for a particular ContactID)the group names of
> the groups they are not a member of. ie Hockey and Netball
> **************
> I already have an SQL that finds the ContactID from tblContacts and
> assigns it to a variable named ContactID. I also have other SQL's
> which finds ALL groups from tblGroups which may or may not be useful.
>
> I think this needs to be done in 2 stages. I look forward to seeing
> your solution.
>
--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"