I have three tables growth_spaces, equipment and growth_space_equipment which links the two tables together. I'm trying to write a query to get all growth spaces that have all of the equipment that I give as an array. For example if the array were ('Mist Propagation, Automated Curtain) I only want growth spaces that have both of these equipment (not ones that have either).

enter image description here

How would I go about writing this in PostgreSQL?

http://sqlfiddle.com/#!15/97b86/2

有帮助吗?

解决方案

You could use LEFT JOIN LATERAL to get a list of all equipment names sorted alphabetically for each growth space, and compare it with another sorted list of elements:

SELECT gs.* 
FROM growth_spaces gs
LEFT JOIN LATERAL (SELECT ARRAY(
  SELECT e.name
  FROM growth_space_equipment gse
  LEFT JOIN equipment e ON (gse.equipment_id = e.id)
  WHERE gse.growth_space_id = gs.id
  ORDER BY e.name) AS names) e ON (true)
WHERE e.names = ARRAY(SELECT UNNEST('{Mist Propagation,Automated Curtain}'::varchar[]) ORDER BY 1)

A variant of this is comparing a list of IDs rather than the texts, which would perform better for large sets:

SELECT gs.* 
FROM growth_spaces gs
LEFT JOIN LATERAL (SELECT ARRAY(SELECT equipment_id FROM growth_space_equipment WHERE growth_space_id = gs.id ORDER BY 1) AS eq_ids) e ON (true)
WHERE e.eq_ids = ARRAY(SELECT id FROM equipment WHERE name IN ('Mist Propagation', 'Automated Curtain') ORDER BY 1)
许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top