我正在嘗試編寫一個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