我遇到了一些问题,想出一个应该很简单的问题。
最初,我有两个数据表,我从中生成了联合结果集;一个事件表,和一个组表(想想社区或组织)。我将使用一个查询来获取事件数据,例如事件名称、ID、承载事件的组(仅为单个ID )等。每个事件和组都有自己的唯一ID号,由AUTO_INCREMENT提供。我将使用以下查询:
SELECT g.group_id,
g.name,
prev_id,
activity_state+0,
state,
first_event_id,
last_event_id,
GROUP_CONCAT(e.event_id ORDER BY start_date_time SEPARATOR ','),
GROUP_CONCAT(e.name ORDER BY start_date_time SEPARATOR '__'),
GROUP_CONCAT(start_date_time ORDER BY start_date_time SEPARATOR ',') AS first_dates,
GROUP_CONCAT(end_date_time ORDER BY start_date_time SEPARATOR ',')
FROM events e
INNER JOIN groups g ON e.group_id=g.group_id
WHERE start_date_time BETWEEN ? AND ?
GROUP BY g.name
ORDER BY first_dates这两个问号表示准备好的语句中的两个绑定日期和时间。这个查询会非常好。
然而,我最近更新了数据库的结构,以包括所谓的“联合事件”,其中多个组共同主持相同的事件。我添加了一个joint_event表,它只包含一个event_id列和一个group_id列。同一事件is在表中多次出现(至少两次),用于指示承载特定事件的组。联合事件也被添加到事件表中,但ID为0(零)。
我现在需要一个功能与上面类似的查询。查询必须包括事件表和组表联接条件中的初始结果集,以及与联合事件表中相同条件匹配的任何联合事件。它们必须适当地分组在一起,这样我就不会得到相同数据的副本(每个组应该出现在自己的行中,每组只显示一行)。
另外,SQL-89语法中的联接条件如下:
events.group_id = groups.group_id(给出了大部分结果,至少98%,加上.)
events.event_id = joint_events.event_id AND joint_events.group_id = groups.group_id(联合活动)
我尝试过使用UNION,但它似乎不支持按返回的整个数据集进行分组。我尝试过使用子查询,但是在使用别名来描述两个单独的数据结果集中的相同列时会遇到问题,因为它通常会产生一个“模糊”的列名错误。使用DISTINCT不起作用,因为它将删除名称完全相同的事件(需要保留这些事件),或者在不应用于需要分组的所有四个列时,在分组列中创建一个不一致性。我最近看到的是一个查询,它导致联合事件数据与其他事件数据分离,而不是被分组到其他事件中;或者数据被包含,但是事件数据被复制。
我不能在任何地方使用NULL,也不能使用两个完全独立的查询,否则我将不得不重构我的PHP脚本,并且可能会使使用PHP对数据进行排序的操作效率低下。
提前谢谢。
发布于 2018-12-30 08:13:53
我算出来了。该解决方案首先关注组ID、事件ID和start_date_time字段,这些字段被相关条件过滤并放入派生表中。然后在它周围放置一个外部查询,负责收集所有必需的字段,将它们组合在一起,并根据派生的"first_dates“字段进行排序。查询以SQL-89语法表示(同样,问号以准备好的语句格式表示绑定日期):
SELECT g.group_id,
g.name,
prev_id,
activity_state+0,
state,
first_event_id,
last_event_id,
GROUP_CONCAT(e.event_id ORDER BY e.start_date_time),
GROUP_CONCAT(e.name ORDER BY e.start_date_time SEPARATOR '__'),
GROUP_CONCAT(e.start_date_time ORDER BY e.start_date_time) AS first_dates,
GROUP_CONCAT(end_date_time ORDER BY e.start_date_time)
FROM events e, groups g, (SELECT DISTINCT g.group_id,
e.event_id,
start_date_time
FROM events e, groups g, joint_events j
WHERE (e.group_id=g.group_id OR (e.event_id=j.event_id AND j.group_id=g.group_id)) AND start_date_time BETWEEN ? AND ?) t
WHERE g.group_id=t.group_id AND e.event_id=t.event_id
GROUP BY g.group_id
ORDER BY first_dateshttps://dba.stackexchange.com/questions/225968
复制相似问题