Reputation: 1051
Suppose I have these tables:
items
, which stores items.
CREATE TABLE items
(
id serial NOT NULL,
name character varying(255),
rarity character varying(255),
created_at timestamp without time zone,
updated_at timestamp without time zone,
CONSTRAINT items_pkey PRIMARY KEY (id)
)
item_modifiers
, which manages the many-to-many relationship between items and modifiers
CREATE TABLE item_modifiers
(
id serial NOT NULL,
item_id integer,
modifier_id integer,
primary_value integer,
secondary_value integer,
CONSTRAINT item_modifiers_pkey PRIMARY KEY (id)
)
modifiers
, which contains all possible item modifiers
CREATE TABLE modifiers
(
id serial NOT NULL,
name character varying(255),
CONSTRAINT explicit_mods_pkey PRIMARY KEY (id)
)
Now suppose I have a complex query. I want to find all items that have modifiers with ID 1 and 2, ordered by the primary_value of the modifier with ID 1.
I have tried this query
SELECT "items".*, item_modifiers.primary_value FROM "items"
INNER JOIN item_modifiers ON item_modifiers.item_id = items.id
AND ((item_modifiers.modifier_id = 1)
OR (item_modifiers.modifier_id = 2))
GROUP BY items.id, item_modifiers.primary_value
HAVING
COUNT(item_modifiers.id) = 2
ORDER BY item_modifiers.primary_value DESC
But it returns an empty result set. However when I don't group by the primary_value, it does, but then I can't order it. I've been stuck on this for ages, so any help is greatly appreciated.
EDIT I have built an SQL fiddle to demonstrate http://sqlfiddle.com/#!15/30887/1
Upvotes: 1
Views: 173
Reputation: 4129
Is this what you are looking for :
SELECT "items".*,
item_modifiers.primary_value
FROM "items"
INNER JOIN item_modifiers
ON item_modifiers.item_id = items.id
AND ( ( item_modifiers.modifier_id = 1 )
OR ( item_modifiers.modifier_id = 2 ) )
ORDER BY item_modifiers.primary_value DESC;
Upvotes: 0
Reputation: 94884
You don't have to join with item_modifiers with the modifier_id 2, you only want it guaranteed that such a records EXISTS:
SELECT items.*, item_modifiers.primary_value
FROM items
INNER JOIN item_modifiers ON item_modifiers.item_id = items.id AND item_modifiers.modifier_id = 1
WHERE EXISTS
(
SELECT *
FROM item_modifiers
WHERE item_modifiers.item_id = items.id AND item_modifiers.modifier_id = 2
)
ORDER BY item_modifiers.primary_value DESC;
Here is your SQL fiddle: http://sqlfiddle.com/#!15/30887/9
Upvotes: 1