我正在寻找最简单,最有效的SQL查询来team从给定的单元中检索单个查询event.但是event可能与team它没有直接关系,它可能与表关系层次结构中的任何级别相关.
这是我的架构的简单表示:
有几点需要注意:
teams可以有很多collections,apps和webhooks.collections也可以有很多webhooks.webhooks可以属于team或者collection,但只能属于一个.events 可以属于任何对象,但只能属于一个对象.这似乎是大多数SaaS类型公司所拥有的相当基本的设置(例如Slack或Stripe).所有内容都归入"团队",用户可以将其作为成员进行交互.
鉴于该设置,我想创建一个解决...的SQL查询...
找到一个事件的团队
id.
我可以轻松编写直接或间接通过特定方式查找父团队的查询.例如...
找到直接相关的"团队活动"团队.
SELECT teams.*
FROM teams
JOIN events ON events.team_id = teams.id
WHERE events.id = ${id}
要么...
找到间接相关的"收集活动" 团队.
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN events ON events.collection_id = collections.id
WHERE events.id = ${id}
Webhooks变得更复杂,因为它们可以通过两种不同的方式相关联......
找到间接相关的"webhook事件" 团队.
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN webhooks AS team_webhooks ON team_webhooks.team_id = teams.id
JOIN webhooks AS collection_webhooks ON collection_webhooks.collection_id = collections.id
JOIN events AS team_webhook_events ON team_webhook_events.webhook_id = team_webhooks.id
JOIN events AS collection_webhook_events ON collection_webhook_events.webhook_id = collection_webhooks.id
WHERE team_webhook_events.id = ${id}
OR collection_webhook_events.id = ${id}
我不确定我是应该这样写,还是UNION改用...
SELECT teams.*
FROM teams
JOIN webhooks ON webhooks.team_id = teams.id
JOIN events ON events.webhook_id = webhooks.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN webhooks ON webhooks.collection_id = collections.id
JOIN events ON events.webhook_id = webhooks.id
WHERE events.id = ${id}
......不确定哪种性能更好.
正如您所看到的,通过所有这些路径,单个事件与给定团队相关的方式有很多种!因此,当我尝试编写"全包围"查询时,它最终变得非常复杂......
这样做UNION,我想我可以做出一堆查询,并将它们组合在一起,虽然这似乎可能是浪费?
SELECT teams.*
FROM teams
JOIN events ON events.team_id = teams.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN apps ON apps.team_id = teams.id
JOIN events ON events.app_id = apps.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN events ON events.collection_id = collections.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN webhooks ON webhooks.team_id = teams.id
JOIN events ON events.webhook_id = webhooks.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN webhooks ON webhooks.collection_id = collections.id
JOIN events ON events.webhook_id = webhooks.id
WHERE events.id = ${id}
使用多个JOINs我想我可能能够加入所有不同的事件所有者组合,与他们的关系teams?虽然这似乎也很多JOIN......
SELECT teams.*
FROM teams
JOIN apps ON apps.team_id = teams.id
JOIN collections ON collections.team_id = teams.id
JOIN webhooks AS team_webhooks ON team_webhooks.team_id = teams.id
JOIN webhooks AS collection_webhooks ON collection_webhooks.collection_id = collections.id
JOIN events AS app_events ON app_events.app_id = apps.id
JOIN events AS collection_events ON collection_events.collection_id = collections.id
JOIN events AS team_events ON team_events.team_id = teams.id
JOIN events AS collection_webhook_events ON collection_webhook_events.webhook_id = collection_webhooks.id
JOIN events AS team_webhook_events ON team_webhook_events.webhook_id = team_webhooks.id
WHERE app_events.id = ${id}
OR collection_events.id = ${id}
OR team_events.id = ${id}
OR collection_webhook_events.id = ${id}
OR team_webhook_events.id = ${id}
编辑:我不认为这个问题是重复的!
昨天,我问"如何查询SQL中的嵌套关系?" ,它涉及类似的数据结构(因为它是相同的),并以类似的方式编写.但是,据我所知,这个问题实际上与此问题相反.
在第一次,我问如何......
通过ID查找与给定用户相关(直接或间接)的所有事件.或者更一般地说,给定"父"的ID,在树状数据模型中找到所有可能的后代.
但在这一个,我问如何......
按ID查找任意事件的团队.或者更一般地说,给定一个任意"子"的ID,可以将其附加到层次结构的任何级别的树状数据模型中,找到其匹配的父级.(这基本上与第一个问题相反.)
据我所知,它们涉及不同的解决方案.第一个似乎涉及在遍历树时执行一系列查询,收集所有事件.第二个(这个),我不太确定,但似乎需要首先构建所有连接的模型,然后检查它们中的哪一个匹配特定事件.
请帮我把它标记为不重复!
双重编辑:好的,不再标记为重复!感谢:D
通过 ID 查找任意赛事的队伍:
从事件表中获取左连接并查看哪个对象返回 team_id 使用它。
select coalesce(e.team_id,a.team_id,c.team_id,w.team_id) eteam_id 
from events e 
   left join apps a on e.app_id=a.id 
   left join collections c on c.id=e.collection_id 
   left join webhooks w on w.id=e.webhook_id 
   left join teams t on t.id=e.team_id 
where e.id=${id};
如果您想要最终团队的所有数据,只是为了完整起见:
select t.* from teams t 
join 
(select coalesce(e.team_id,a.team_id,c.team_id,w.team_id) eteam_id
from events e left join apps a on e.app_id=a.id 
left join collections c on c.id=e.collection_id 
left join webhooks w on w.id=e.webhook_id 
left join teams t on t.id=e.team_id 
where e.id=1) t1 
on t.id=eteam_id;
| 归档时间: | 
 | 
| 查看次数: | 417 次 | 
| 最近记录: |