Click here to Skip to main content
15,887,267 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
So, I have a database structure like so:

Messages
-------------
MessageID (PK)
Text
Etc...


MessageContact
--------------
MessageID (FK)
ContactID (FK)


Contacts
---------
ContactID
FirstName
LastName


My MessageContact table joins the Messages and Contacts tables. A message may have many contacts it was sent to, and a contact may have had many messages sent to them. My web form allows a user to select a number of Contacts and search for all messages with that set of contacts. My problem is I have no idea how to form the query to perform such a search. I was thinking of doing something with taking in the Contacts as an array an looping through, eliminating message records as certain contacts weren't found, but that would mean pulling all the messages in the database, and that seems wrong.

Any help would be appreciated. Thanks!
Posted
Updated 26-Jun-13 4:48am
v2

Avoid looping through an array or table if you can. Try something like

SQL
SELECT M.*  -- replace with list of stuff from Messages you need
, C.*   -- replace with list of stuff from Contacts you need
FROM Messages M
INNER JOIN MessageContact MC on M.MessageID=MC.MessageID
INNER JOIN Contacts C on C.ContactID=MC.ContactID
WHERE ContactID in (...)
ORDER BY ContactID, MessageID

You will need to replace the (...) above with a comma-separated list of the contacts selected from your web form e.g. ('1','2','3')
OR
you could insert the contacts into an interim table (e.g. SelectedContacts) and use
WHERE ContactID in (Select ContactID from SelectedContacts)


[Edit - see comments below]
This is a bit mangled as I haven't got anything to run it against on this PC. I'm trying to say just return messages that have been sent to the listed contacts and where the number of recipients for those messages is the same as the count of contacts. There is definitely a tidier way of doing it!
SELECT M.*  -- replace with list of stuff from Messages you need
, C.*   -- replace with list of stuff from Contacts you need
FROM Messages M
INNER JOIN MessageContact MC on M.MessageID=MC.MessageID
INNER JOIN Contacts C on C.ContactID=MC.ContactID
WHERE M.MessageID in
    (Select MessageID from MessageContact M
        where ContactID in
         (Select ContactID from SelectedContacts)
    Group by MessageID
    Having count(*) = (select count(*) as ContactCount from SelectedContacts))
 
Share this answer
 
v2
Comments
Jack R. Schaible 26-Jun-13 11:06am    
Thanks for your reply! However, for example, say I have contact id's 8 and 9. Would it not return all message records that had contact id 8 in it? I would need to exclude records where it had only one of the contact id's in it...
CHill60 26-Jun-13 11:12am    
Yes you are correct - my code would return all of the records for contact 8. So am I right that you only want the messages that have been sent to ALL of the selected contacts (and ignore any messages that were sent to only 1 or some of the selected contacts) - sorry for the misunderstanding
[edit] - I saw something similar a few months ago, I'm just trying to find it!
Jack R. Schaible 26-Jun-13 11:16am    
Oh, no problem! Sorry if I was unclear!
CHill60 26-Jun-13 11:34am    
Nope - it's me - I'm having a fuzzy head day. I've updated my solution... but see my comments to the update!
I eventually found an article here that explains how to do several types of queries on a multi-to-multi table join: http://www.sergiy.ca/how-to-write-many-to-many-search-queries-in-mysql-and-hibernate/[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900