我正在尝试编写一个SQL查询以生成给定用户在给定时段执行的操作的汇总行。我有以下相关的表结构:为多个表中的数据创建汇总行
用户
- ID
- 队
audit_periods(可处理,运输,休息等)
- USER_ID
- period_type(可以是“处理”,“sh ipping”等 - 当前未归一化)
- started_at
- finished_at(可以为空当期,因此围绕下面倍逻辑)
audit_tasks
- audit_period_id
- audit_task_type_id
- created_at
- 得分 个
audit_task_types
- 名称( “扫描”, “place_in_pallet” 等)
- 得分(似乎是多余的,但我们需要保持得分,在它被执行的时候收到的audit_task作为audit_task_type得分以后可以更改)
对于每个用户对于给定的牙周d,我想创造这样的数据的一行:
users.id users.email time_spent_processing time_spent_shipping ... number_of_scans number_of_pallets
这会搞清楚每个用户来计算:
- 什么audit_periods至少部分落在所需的窗口? (使用started_at和finished_at。)
- 用户在每种类型的audit_period中花费了多长时间? (应该涉及到audit_periods.period_type组,我想象一下。)
- 什么audit_tasks属于所需的窗口? (使用created_at - 尚未在下面的代码中。)
- 用户在窗口期间完成的每种audit_task类型有多少? (加入audit_task_type,可能涉及到一个由audit_task_types.name组成的团队。)
- 在此期间赚了多少分? (总计窗口中所有audit_tasks的分数。)
我已用尽了所有的招数SQL我知道(不是很多),并与像想出了以下内容:
select
u.id as user_id,
u.email as email,
u.team as team,
ap.period_type as period_type,
att.name,
time_to_sec(
timediff(least("2011-03-17 00:00:00", ifnull(ap.finished_at, utc_timestamp())), greatest("2011-03-16 00:00:00", ap.started_at))
) as period_duration,
sum(at.score) as period_score
from audit_periods as ap
inner join users as u on ap.user_id = u.id
left join audit_tasks as at on at.audit_period_id = ap.id
left join audit_task_types as att on at.audit_task_type_id = att.id
where (ap.started_at >= "2011-03-16 00:00:00" or (ap.finished_at >= "2011-03-17 00:00:00" and ap.finished_at <= "2011-03-17 00:00:00"))
and (ap.finished_at <= "2011-03-17 00:00:00" or (ap.started_at >= "2011-03-16 00:00:00" and ap.started_at <= "2011-03-16 00:00:00"))
and u.team in ("Foo", "Bar")
group by u.id, ap.id, at.id
但这似乎在功能上等同于只选择所有的审计任务到底。我也尝试过一些子查询,但效果不佳。更直接地说,这将产生类似(跳过不太重要的列):
user_id | period_type | period_duration | name | score
1 processing 1800s scan 200
1 shipping 1000s place_in_pallet 100
1 shipping 1000s place_in_pallet 100
1 break 500s null null
时,我想:
user_id | processing | shipping | break | scan | place_in_pallet | score
1 1800s 1000s 500s 1 2 400
我可以很容易地获取所有audit_tasks的给定用户和卷起来的代码,但是我可能会在给定的时间段内获取数十万个audit_tasks,所以需要在SQL中完成。
只是要清楚 - 我正在寻找一个查询来为每个用户生成一行,其中包含在其他3个表中收集的摘要数据。因此,对于每个用户,我想知道他在每种类型的audit_period(3600秒处理,3200秒运输等)中花了多少时间,以及他执行的每个audit_task有多少次(5次扫描,10个项目放置在托盘等)。
我想我有一个解决方案的元素,我只是无法将它们拼接在一起。我确切地知道我会如何在Ruby/Java /等中实现这一点,但我不认为我理解SQL足以知道我错过了哪个工具。我需要临时表吗?工会?其他一些构造完全?
任何帮助,非常感谢,我可以澄清,如果上述是完全废话。
我暂时删除了我的帖子,因为它发生在我身上,还有更多我们需要知道。目前尚不清楚如何找到“可以加工”的任务。我们需要更多地了解表格的结构。如何在模式中实际定义“time_spent_shipping”?什么是“扫描”,它们存储在哪里?托盘计数如何存储等 – Thomas 2011-03-17 06:05:43
顺便说一句,您的查询和我的每个用户每个周期返回一行的原因是您(和我)正在Audit_Period.Id和Audit_Tasks.Id上分组。假设Id是表格的PK,那么您将为每个表格返回一行。 – Thomas 2011-03-17 06:07:44
@Thomas - 我编辑了这个问题来更好地阐明表格结构。希望这已经足够了,但如果不是,我可以再刺一次。我明白为什么我们的查询返回多行。我不明白的部分是如何有效地将这些行中包含的信息合并到一行中。我猜测我有一种我以前从未见过的伎俩,或者我可以忽略的东西。 – Kyle 2011-03-17 06:16:36