【问题标题】:SQL One-To-Many return & group by search conditionSQL 一对多返回和按搜索条件分组
【发布时间】:2013-08-05 12:09:42
【问题描述】:

大家好,亲爱的overflowers,希望大家有脑采摘;一如既往,非常感谢! :)

我有一个事件表,可以分配多个类别(用作标签):

然后我有类别(存储每个标签)和 Events_Categories(链接表)

**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   

以上总结

Basketball            => Sports 
Children Charity Ball => Charity 
Bowling Charity       => Charity & Sports 

期望的结果

我希望能够搜索“运动”标签,这将返回所有具有该标签的事件。但是,它需要返回(和分组)与该特定事件关联的所有标签。

IE 搜索“Sport”标签会返回:

**Events**
| id  |       event_name      |  tags         |
+---------------------------------------------+
+ 1   | Basketball            | sport
+ 3   | Bowling Charity Event | sport, charity

返回没有 WHERE 条件的事件的 SQL 示例: 以下 SQL 返回所有事件并对类别(或标签)进行分组。这应该让您了解我的数据库结构,可能对解决方案有所帮助?

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`;

附加问题(额外的布朗尼积分)

你能相信吗,他想要更多的帮助!! :)

此外,在链接表中,实际上还有另一个字段用于事件何时链接到 Activity:

**Events_Categories** (Linking Table)
| event_id  | event_category_id | activity_id |
+---------------------------------------------+
+    1      |       1           |     1
+    2      |       2           |
+    3      |       1           |     2
+    3      |       2           |     2

我将如何搜索活动 ID 为 [x] 的事件以返回事件详细信息,再次将所有标签分组:

链接到 2 个关联的 Activity_ID 的事件

| id  |       event_name      |  tags          | activity_id |
+------------------------------------------------------------+
+ 3   | Bowling Charity Event | sport, charity |     2

再次感谢!

【问题讨论】:

  • 你能给出你想要的结果的样本记录吗?
  • 您使用的是什么 RDMBS?
  • @491243 - 我已经更新了。谢谢

标签: mysql sql group-by concatenation one-to-many


【解决方案1】:

这将回答您问题的第一部分。为了获取事件中包含的所有类别的列表,您可以使用EXISTS 检查该事件是否至少包含您的搜索事件名称的一部分。

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

更新 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

【讨论】:

  • 对于问题的第二部分,一个事件是否有可能有不同的activity_id
  • 事件将只有一个(如果有)activity_id。活动更像组。 IE 我们的足球队,在他们的活动页面上,将显示相关的事件。此 SQL 语句中的标记将无关紧要(但标记会更好地了解 /tag/search 上的事件)
  • 那么在第二部分,你不需要搜索标签吗?
  • 抱歉打错了,应该是HAVING MAX(activity_id) = 2
  • 我应该意识到这一点。再次感谢,您的帮助非常宝贵。 - 需要避免聊天,但同样要表达我的感激之情!
猜你喜欢
  • 2021-10-05
  • 2010-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多