我试图找出哪些成员在最近 x 场事件中出席率最高,其中事件类型很重要
示例结构在这里
http://sqlfiddle.com/#!2/bde53/1
attended_id
是成员 id,鉴于许多事件具有许多事件类型,如果可能的话我希望这样
attended_id | last 6 event 1 | last 12 event 2 | 2013 event 3 |
1 6 10 6
2 5 9 12
3 2 8 7
2013 event 3
表示2013年发生的所有事件id为3
这是可能的还是最好导出到 excel 以获取此信息?
如果新结构使此查询更容易,也对新结构开放。这些数字应该很容易改变,例如获取最后 8 个事件 1 而不是最后 6 个
我每个都有 SQL 但不能将它们组合起来
按成员(member)id分类的去年事件
SELECT attended_id, year(x.date), count(event_id) FROM events e INNER JOIN events_types x USING (event_id)
INNER JOIN events_type t USING (event_type)
WHERE t.event_type = 1
group by attended_id, year(x.`date`);
类型的最后 x 个事件
SELECT attended_id, count(event_id) FROM events e INNER JOIN events_types x USING (event_id)
INNER JOIN events_type t USING (event_type)
WHERE t.event_type = 1 and
e.event_id >= (
select event_id from events_types where event_type = 1 order by event_id desc
limit 1,1
)
group by attended_id
我只是不能将它们组合起来以在同一个查询中显示它们
最佳答案
查询可以通过以下方式实现:
- 使用user defined variables一次计算出每个事件类型的年龄排名
- 将考勤记录加入排名结果,按
attended_id
分组
这是查询:
select
a.attended_id,
sum(event_type = 1 and rank <= 6) `last 6 event 1`,
sum(event_type = 2 and rank <= 12) `last 12 event 2`,
sum(event_type = 3 and year(date) = 2013) `2013 event 3`
from events a
left join (
select event_id, event_type, date,
(@row := if(@prev is null or @row is null or @prev != event_type, 1, @row + 1)) rank,
(@prev := event_type) prev
from (select event_id, event_type, date
from events_types
order by event_type, date desc) e) r on r.event_id = a.event_id
group by 1
这是 SQLFiddle
如您所见,将变量更改为具有不同的事件类型和“最后 n 个”值,甚至为不同的分割添加更多列都是一件简单的事情。
注意事项:
- 最里面的查询按事件然后日期从旧到新对行进行排序。这是排名逻辑正常工作所必需的
- 变量为
null
的测试仅在第一行需要,但用于避免必须在单独的语句中定义变量,使查询成为一个独立的查询,这通常是必需的,因为大多数数据库库不支持在单个调用中执行多个查询 - 冗长的
case
语句通过求和一个条件来避免;在 mysql 中, bool 值是 1 表示真,0 表示假,所以求和一个条件计数它为真的次数
最后一点,您的表名有点困惑。可以更改它们以使它们的含义更清楚。我建议这些更改:
events
-->attendances
events_types
-->events
events_type
-->event_types
关于mysql - 类型的最后 x 个事件的 SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20752508/