简体   繁体   中英

Multiple many-to-many relationships in SQL

How can I query multiple many-to-many relationships in the same result set?

I have two tables that I typically always LEFT JOIN for a standard result set:

tblPROJECTS-

id  |  jobnumber  |  jobname ...
--------------------------------------------------
1   |  1000       |  Project X
2   |  2000       |  Project Y
3   |  3000       |  Project Z

tblTASKS-

id  |  tasknumber |  jobnumber  |  taskname ...
--------------------------------------------------
1   |  10         |  1000       |  Project X: Task 1
2   |  20         |  1000       |  Project X: Task 2
3   |  30         |  2000       |  Project Y: Task 1

Tasknumber is a GUID, independent of jobnumber, but will never be related to more than one job.

I LEFT JOIN tblTASKS on jobnumber, since not all projects will have tasks (yet)

But then I also have an owners table that defines 1-n users who own either the job as a whole or the individual tasks (or both). Each user can own multiple jobs and/or tasks. The original design of the DB spec'd that a single table be used.

tblOWNERS-

id  |  ownertype  |  ownerid  |  jobnumber  |  tasknumber ...
----------------------------------------------------------------
1   |  1          |  2        |  1000       |
2   |  1          |  4        |  1000       |
3   |  2          |  2        |             |  10

An ownertype of 1 indicates the user owns the overall job. An ownertype of 2 indicates the user owns the task within the job.

I have two queries that I'm trying to construct:

1) Return the job with all associates job owners, joined with all tasks for that job with all associated task owners.

jobnumber |  jobowners | tasknumber | taskowners ...
1000      |  2,4,...   | 10         | 2
2000      |            | 20         | 4,6,8...
3000      |  4,5,6...  | 30         | 

2) Given an owner ID, return all the jobs and/or tasks they are associated with.

It's the multiple many-to-many from/to the same tables that has me stumped. Can I accomplish this? If so, am I looking for some sort of UNION or INTERSECT (what do I look up to learn)? Or, if not, what's the better schema for relationships like this that would allow for it?

TIA!

Generally, you need to place the foreign key in the many end of an ERD, so in this case you might have a field called 'ownerid' in the table 'tblPROJECTS', as well as having 'ownerid' in tblTASKS. Assuming then that all tasks have a job ID and an owner, and all projects also have an owner, you can use INNER JOINs:

SELECT P.jobnumber,T.tasknumber,O1.id AS taskowner,O2.id AS jobowner
FROM tblTASKS T
INNER JOIN tblPROJECTS P ON P.jobnumber=T.jobnumber
INNER JOIN tblOWNERS O1 ON O1.id=T.ownerid
INNER JOIN tblOWNERS O2 ON O2.id=P.ownerid
WHERE O1.id=1

This will not concatenate the jobowners and task owners as you have described, but will return a row for each, which you can then concatenate whilst processing the resultset.

Then just replace the WHERE clause as necessary to get the list of tasks for a given Job number...

WHERE P.jobnumber=1000

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM