views:

32

answers:

2

The parameters are thus:

  1. I have a table called Tasks with columns ID (primary key) and label (text).
  2. I have another table called Locations with a foreign key referencing Tasks' ID and a name for a location (text).
  3. In my code I have a set of locations.
  4. UPDATED: I need a query to return all tasks that have associated locations found within my set. Each task that has an associated location not found in my set must be thrown out.

What's the best way to go about this?

A: 

select * from tasks where id in (select unique task_id from locations where name in ('London', 'Geneva'...))

Don't forget to add an index on locations(name)

vc 74
But what about tasks with at least 1 location not in my set? Are those filtered with this?
Hamster
Nope, (select unique task_id from locations where name in ('London', 'Geneva'...) is going to return the IDs of the tasks that have at least one of the locations in your list, these IDs are then used to retrieve each task's detail
vc 74
So you mean I need to do that last bit of filtering in my code...?
Hamster
No you won't have to, if I understood you correctly, the query will return the tasks you're interested in, no more, no less
vc 74
A: 

For the modified requirement:

select * from tasks t
where exists (select null from locations l
              where t.id = l.task_id and l.name in ('London', 'Geneva'...)) and
  not exists (select null from locations l
              where t.id = l.task_id and l.name not in ('London', 'Geneva'...))
Mark Bannister
I think this might work. I also earlier finally managed to come up with:SELECT * FROM Tasks WHERE id NOT IN (SELECT UNIQUE L.taskid FROM Locations L WHERE L.val NOT IN ('London', 'Geneva', ...)); I'm not sure if mine is correct, though.
Hamster