SQL One-To-Many return & group by search condition

旧巷老猫 提交于 2019-12-11 11:31:44

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!