2011-06-23 53 views
0

我正在向查詢銷售員狀態的表格寫入查詢,並跟蹤他們旅行的時間。作爲參考,下面是對這個問題很重要的狀態:正在製作太多表格副本

600初始值:

0旅行打破

601:上破

603:前往午餐

604:在吃午飯

我想要計算一個員工花費旅行的總時間。我能夠返回旅行時間和午餐時間使用

SELECT (cast(c1.status_change_dt as date) - cast(c2.status_change_dt as date)) as LunchTravel, C1.CREW_ID 
FROM CREW_STATUS c1, CREW_STATUS c2 
WHERE c1.status_id = '603' and c2.status_id = '602' 
and c1.mobile_token = c2.mobile_token 

同樣的休息。 Mobile_token是爲了確保它在同一天返回(每個員工每天都得到一個唯一的令牌)。

Status_change_dt是時間戳

我做同樣的事情,但其他STATUS_ID的獲得BreakTravel時間。

所以我最終得到了LunchTravel和BreakTravel,但我覺得創建4個Crew_Status是效率低下的,而且實際上運行速度很慢。

有沒有更好的方法來做到這一點?

+0

你的模式是什麼樣的? –

+0

你有合適的索引嗎? – GolezTrol

回答

1

如果我理解你的問題,我認爲你可以使用UNION ALL或CASE語句。

SELECT (cast(c1.status_change_dt as date) - cast(c2.status_change_dt as date)) 
, CASE WHEN c1.status_id = '603' and c2.status_id = '602' THEN 'Lunch Travel' 
,  WHEN c1.status_id = '604' and c2.status_id = '605' THEN 'Break Travel' 
END AS travel_type 
FROM CREW_STATUS c1, CREW_STATUS c2 
WHERE c1.mobile_token = c2.mobile_token 

OR

SELECT (cast(c1.status_change_dt as date) - cast(c2.status_change_dt as date)) as Travel, 'Lunch Travel' AS travel_type, C1.CREW_ID 
FROM CREW_STATUS c1, CREW_STATUS c2 
WHERE c1.status_id = '603' and c2.status_id = '602' 
and c1.mobile_token = c2.mobile_token 

UNION ALL 

SELECT (cast(c1.status_change_dt as date) - cast(c2.status_change_dt as date)) as Travel, 'Break Travel' AS travel_type, C1.CREW_ID 
FROM CREW_STATUS c1, CREW_STATUS c2 
WHERE c1.status_id = '605' and c2.status_id = '606' 
and c1.mobile_token = c2.mobile_token 
+0

是的,對不起,這個問題有點複雜。我肯定會嘗試這個,雖然 – null

0

,而不是試圖加入的狀態(你如何確保一個602後,該行是603?)我會按日期加入得到一個結果是讓你的狀態之間所花費的時間:

SELECT 
    CS1.status_id, 
    CS2.status_change_dt - CS1.status_change_dt -- Use date function here 
FROM 
    Crew_Status CS1 
INNER JOIN Crew_Status CS2 ON 
    CS2.mobile_token = CS1.mobile_token AND 
    CS2.status_change_dt > CS1.status_change_dt 
LEFT OUTER JOIN Crew_Status CS3 ON 
    CS3.mobile_token = CS1.mobile_token AND 
    CS3.status_change_dt > CS1.status_change_dt AND 
    CS3.status_change_dt < CS2.status_change_dt 
WHERE 
    CS3.status_change_dt IS NULL 

然後,您可以通過status_idSUM日期不同羣體得到的總數。

您可能需要添加一些不同的檢查 - 確保CS1.status_id和CS2.status_id有意義(例如602和603)並且佔用過長的時間(如果員工離開會發生什麼情況破發,但隨後沒有進一步的情況會記錄它看起來像他們花了3天的休息

最後,停止試圖監視你的銷售人員的一天每一秒,讓他們做他們的工作;)

+0

感謝您的幫助,哈哈我會傳遞給我的老闆的消息:) – null

0

如果您的數據庫支持它們,那麼使用分析查詢來獲得指示中斷開始的每個狀態的下一個狀態可能就足夠了:

select mobile_token, end_dt - start_dt 
from (select status_id, 
      mobile_token, 
      status_change_dt as start_dt, 
      lead(status_change_dt) over (partition by mobile_token 
              order by status_change_dt) as end_dt 
     from Crew_Status) 
where status_id in (600, 603) 

很明顯,如果你可以有600沒有601(例如),這將不會工作得特別好(返回的時間段將是600到任何接下來發生的事情)。另外,指定你正在使用哪個數據庫總是一個好主意,因爲它們之間的功能可能有很大不同。