问题
Hello again beloved overflowers, I hope we have some brains available for the picking; as always it's greatly appreciated! :)
I have an Events table, which can be assigned multiple categories (used as tags):
I then have the Categories (stores each tag) and Events_Categories (linking table)
**Events**
| id | event_name |
+------------+
+ 1 | Basketball
+ 2 | Children Charity Ball
+ 3 | Bowling Charity Event
**Event_Categories** (Stores Tags / Categories)
| id | name |
+------------+
+ 1 | sport
+ 2 | charity
+ 3 | other_tag
**Events_Categories** (Linking Table)
| event_id | event_category_id |
+-------------------------------+
+ 1 | 1
+ 2 | 2
+ 3 | 1
+ 3 | 2
Summary of above
Basketball => Sports
Children Charity Ball => Charity
Bowling Charity => Charity & Sports
Desired Result
I want to be able to search for 'Sport' tag, which would return all events which have that tag. BUT, it needs to return (and group) all the tags associated with that particular event.
IE searching for 'Sport' tag would return:
**Events**
| id | event_name | tags |
+---------------------------------------------+
+ 1 | Basketball | sport
+ 3 | Bowling Charity Event | sport, charity
SQL Example returning Events without WHERE conditions: The following SQL, returns all events and groups the categories (or tags). This should give you an idea of my DB structure, possibly help with the solution?
SELECT e.*, group_concat(c.name) as tags
FROM `events` e
JOIN `events_categories` ec
ON e.`id` = ec.`event_id`
JOIN `event_categories` c
ON ec.`event_category_id` = c.`id`
GROUP BY e.`id`;
Additional Question (for extra brownie points)
Can you believe it, HE WANTS MORE HELP!! :)
Also, in the linking table, there is actually another field for when the events link to an Activity:
**Events_Categories** (Linking Table)
| event_id | event_category_id | activity_id |
+---------------------------------------------+
+ 1 | 1 | 1
+ 2 | 2 |
+ 3 | 1 | 2
+ 3 | 2 | 2
How would I search for an event, with the Activity ID of [x] to return the event details, again with all the tags grouped:
Events which link to Activity_ID of 2 associated
| id | event_name | tags | activity_id |
+------------------------------------------------------------+
+ 3 | Bowling Charity Event | sport, charity | 2
Thanks so much, once again!
回答1:
This will answer the first part of your question. In order to get the list of all categories contain in an event, you can use EXISTS
to check if the event contains atleast a portion of your search event name.
SELECT a.ID,
a.Event_name,
GROUP_CONCAT(c.Name)
FROM Events a
INNER JOIN Events_Categories b
ON a.ID = b.event_ID
INNER JOIN Event_Categories c
ON b.event_category_id = c.ID
WHERE EXISTS
(
SELECT 1
FROM Events_Categories d
INNER JOIN Event_Categories e
ON d.event_category_id = e.id
WHERE e.Name = 'Sport' AND
d.event_id = a.id
)
GROUP BY a.ID,
a.Event_name
- SQLFiddle Demo
UPDATE 1
SELECT a.ID,
a.Event_name,
GROUP_CONCAT(c.Name) CategoryList,
MAX(activity_id) activity_id
FROM Events a
INNER JOIN Events_Categories b
ON a.ID = b.event_ID
INNER JOIN Event_Categories c
ON b.event_category_id = c.ID
GROUP BY a.ID, a.Event_name
HAVING MAX(activity_id) = 2
- SQLFiddle Demo
来源:https://stackoverflow.com/questions/18047093/sql-one-to-many-return-group-by-search-condition