Pregunta

If I use:

SELECT *
  FROM "moves"
 INNER
  JOIN "move_conditions"
    ON "move_conditions"."move_id" = "moves"."id"
 INNER
  JOIN "conditions"
    ON "conditions"."id" = "move_conditions"."condition_id"
 WHERE "conditions"."id" IN (29, 3)

This returns the correct tables where conditions have an id of 29 or 3.

However, if I try:

SELECT *
  FROM "moves"
 INNER
  JOIN "move_conditions"
    ON "move_conditions"."move_id" = "moves"."id"
 INNER
  JOIN "conditions"
    ON "conditions"."id" = "move_conditions"."condition_id"
 WHERE "conditions"."id" NOT IN (29, 3)

The result is incorrect. Conditions with id 29 or 3 are in the result. They should not be. How do I fix this?

¿Fue útil?

Solución

Do you mean that you want to disqualify a move if any of its conditions is 29 or 3? I'd try a subquery for that.

SELECT *
  FROM "moves"
WHERE moves.id
NOT IN 
    (SELECT /* Don't know if PG infers or would be faster
                 with the DISTINCT that is implied by NOT IN */
      moves.id FROM 
      move_conditions 
      INNER JOIN
      conditions
    ON move_conditions.condition_id=conditions.id
    WHERE conditions.id IN (29,3)
    )

Or you could try

SELECT *
  FROM moves
EXCEPT
SELECT *
  FROM "moves"
INNER
JOIN "move_conditions"
   ON "move_conditions"."move_id" = "moves"."id"
INNER
JOIN "conditions"
ON "conditions"."id" = "move_conditions"."condition_id"
WHERE "conditions"."id" IN (29, 3)

although I'd expect that to be much slower.

You can convert the first version to use NOT EXISTS instead of NOT IN; versions of PG optimize those differently and one may be faster than the other.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top