Reputation: 353
I have two tables, Event
and EventTag
CREATE TABLE event (
id INT PRIMARY KEY,
content TEXT
)
CREATE TABLE event_tag (
event_id INT,
type VARCHAR(255),
value VARCHAR(255)
)
Each event has zero or more tags. The query I'd like to express in SQL is:
Give me all
Event
(all columns in the table) that have associated tags withEventTag.type="foo" and EventTag.value="bar"
.
This is easy for one tag criterion (for example, with a join and a where, as answered here), but how do I tackle the situation of two or more criteria? So: Give me the events that have an associated tag "foo" equal to "bar" and (!) an event tag "qux" equal to "quux"? I thought about joining the tag table 'n' times, but I'm not sure if it's a good idea.
Upvotes: 0
Views: 757
Reputation: 47464
The best way to solve this problem is to not use the EAV database model (Entity-Attribute-Value). You're running into just the first of many problems with this anti-pattern. A quick Google search on "EAV model" should reveal some of the other problems in store for you if you choose not to redesign. Normally your Event
table should have a column for foo
and a column for qux
.
One possible solution that you can use, if you insist (or are forced) to go down this path:
SELECT id, content
FROM Event
WHERE id IN
(
SELECT
E.id
FROM
Event E
INNER JOIN Event_Tag T ON
T.event_id = E.id AND
(
(T.type = 'foo' AND T.value = 'bar') OR
(T.type = 'qux' AND T.value = 'quux')
)
GROUP BY
E.id
HAVING
COUNT(*) = 2
)
If you put your various type/value pairs into a temporary table or as a CTE then you can JOIN
to that instead of listing out all of the pairs that you want. That syntax will be dependent on your RDBMS though.
Upvotes: 2
Reputation: 402
Select id from EVENT ev
INNER JOIN EVENT_TAG et
ON ev.id = et.event_ID
WHERE et.type = 'foo'
AND et.value = 'bar'
Obviously you can put any thing you want between the parentheses to find what ever types you want.
Upvotes: 0
Reputation: 470
Use Or operand for multiple case/criteria
SELECT * FROM Event e join Event_tag on e.eventId = et.eventtagid where ((EventTag.type="foo" and EventTag.value="bar") or (EventTag.type="po" and EventTag.value="yo"))
or if the values is dyanmic, then depending on your programming language that interface SQL, you can write a query
For example in java I can do it using
SELECT * FROM Event e join Event_tag et on e.eventid = et.eventtagid where (EventTag.type=? and EventTag.value=?)
Where I assign the above SQL string to Query and set the parameters for it.
Upvotes: 0