2014-04-15 27 views
0

我想編寫一個腳本,需要這樣的數據庫條目:PHP複雜的時間總和

╔════╦═════════╦════════╦══════════╗ 
║ id ║ user_id ║ action ║ time ║ 
╠════╬═════════╬════════╬══════════╣ 
║ 1 ║  1 ║  1 ║ 12:00:00 ║ 
║ 2 ║  1 ║  2 ║ 12:10:00 ║ 
║ 3 ║  1 ║  1 ║ 18:00:00 ║ 
║ 4 ║  1 ║  2 ║ 18:10:00 ║ 
╚════╩═════════╩════════╩══════════╝ 

然後工作了兩個動作之間的差額再總結在一起,這個例子總共會有20:00

我真的不知道該從哪裏開始,並且似乎無法在網絡上找到任何有用的信息。

如果有人能指出我正確的方向,或任何幫助將不勝感激。

編輯:其他操作可能在數據庫(1-7)以及多個用戶。

EDIT2:更復雜的例子桌子底下,還應該導致20:00

╔════╦═════════╦════════╦══════════╗ 
║ id ║ user_id ║ action ║ time ║ 
╠════╬═════════╬════════╬══════════╣ 
║ 1 ║  1 ║  1 ║ 12:00:00 ║ 
║ 2 ║  1 ║  2 ║ 12:10:00 ║ 
║ 3 ║  2 ║  1 ║ 12:30:00 ║ 
║ 4 ║  2 ║  2 ║ 12:40:00 ║ 
║ 5 ║  2 ║  3 ║ 12:50:00 ║ 
║ 6 ║  2 ║  4 ║ 13:00:00 ║ 
║ 7 ║  3 ║  1 ║ 14:00:00 ║ 
║ 8 ║  3 ║  2 ║ 14:10:00 ║ 
║ 9 ║  1 ║  1 ║ 18:00:00 ║ 
║ 10 ║  1 ║  2 ║ 18:10:00 ║ 
╚════╩═════════╩════════╩══════════╝ 
+0

也許嘗試更多的股票時間戳比約會時,你可以輕鬆地做更多的計算。 –

+0

我們如何知道我們應該比較'12:00:00'和'12:10:00'而不是'12:00:00'和'18:10:00'?在這兩種情況下,我們都會比較'user_id = 1'和'action = 1'到'user_id = 1'和'action = 2'。另外,有沒有第三個動作的可能性?如果是這樣,你想如何分解? –

+0

@PatrickQ準確地說,這就是我一直在堅持的......我需要某種方式來在做數學之前對它們進行排序。 – jamiestraw

回答

1

這裏的一個PHP端方法噸帽子應該讓你開始。假設$ arrQueryResults是一個從「SELECT * FROM table ORDER BY user_id,time,action」中使用任何適用於您的數據庫的語法的數據庫結果集。

$db = mysqli_connect("server", "username", "password", "database"); 
$query = "SELECT * FROM action WHERE date = '".$todaysDate."' ORDER BY user_id, time, action"; 
$result = mysqli_query($db, $query); 

while ($arrResult = mysqli_fetch_assoc($result)) { // For each row in the query result 
    $user=$arrResult['user_id']; 
    $time=strtotime($arrResult['time']); // Converts H:M:S to an integer timestamp 
    $action=$arrResult['action']; 

    // Add the timestamp for this user and action to track until we have a matched pair 
    if ($action == '2') { 
     $arrUserAction[$user][$action]=$time; 
    } 

    if ($action == '5' && isset($arrUserAction[$user]['2'])) { 
     if (!isset($arrDiffSums[$user])) { // If we have no running total for the user yet, create one. 
      $arrDiffSums[$user]=$time - $arrUserAction[$user]['2']; 
     } else { // IF we have a total for the user already, add to it. 
      $arrDiffSums[$user]=$arrDiffSums[$user] + ($time - $arrUserAction[$user]['2']); 
     } 
     unset($arrUserAction[$user]); // We just added a sum, now remove our tracking to be ready for the next pair. 
    } 
} 
print_r($arrDiffSums); 

這應該導致$ arrDiffSums用戶#秒。在你的第二表例如:

array(
    '1' => 1200, 
    '2' => 1200, 
    '3' => 600 
) 

哪些可以轉換爲H:M:S或其它格式的gmdate();PHP - Convert seconds to Hour:Minute:Second):

foreach ($arrDiffSums as $user => $secs) { 
    print "User: ".$user." Sum: ".gmdate("H:i:s", $secs)."\n"; 
} 
+0

我只是試圖實現它,現在這個代碼是非常先進的,所以請原諒新手的問題......首先,我應該在哪裏打印結果?在foreach之外還是在裏面?這個查詢可以嗎? '$ query = mysql_query(「SELECT * FROM action WHERE date = $ todaysDate ORDER BY user_id,time,action」); while($ row = mysql_fetch_assoc($ query)){$ arrQueryResults [] = $ row [「time」]] ;}' – jamiestraw

+0

已更新爲使您更接近使用mysqli_優先於mysql_驅動程序(已棄用)。 – Jef

+0

同樣,@Patrick Q指出,有很多假設都可以應用於此。開始/停止動作#總是連續的?用戶可以同時執行多個操作嗎?如果這些是時鐘時間,那麼你有多確定沒有一個序列與一天的邊界重疊? (即,開始23:50:00停止00:10:00 = 20:00)。想想這些事情。 – Jef

1

同樣的例子討論SQL-FIDDLE後http://sqlfiddle.com/#!2/8e5ab/5

-

SQL-FIDDLEhttp://sqlfiddle.com/#!2/ab988/1

SELECT user_id, SUM(time_difference) as time_spent 
FROM ( 
    SELECT t1.user_id, 
    CASE WHEN t1.user_id = t2.user_id 
    THEN time_to_sec(t2.time_duration) - time_to_sec(t1.time_duration) ELSE 0 END time_difference 
    FROM T t1 LEFT OUTER JOIN T t2 
    ON t1.id = t2.id - 1 
    JOIN (SELECT @DIS := 0)R)TAB1 
GROUP BY user_id; 

這個查詢做了什麼?

  • 該表使用了兩次。計算結果在外部SELECT中可用。
  • 內SELECT(子查詢)執行以下操作:
    • 計算時間差(T2-T1)
    • 當user_id是相同的(USER_ID = USER_ID)
    • 但不同的行(ID-1)
    • 結果是TIME_DIFFERENCE
  • 外SELECT得到TIME_DIFFERENCE和概括起來

現在,您可以在幾秒鐘內獲得time_spent。 如果你希望你的準確結果'20:00' ,你可能會改變第一線,其中包括一個時間轉換,就像這樣:

SELECT user_id, TIME_FORMAT(SEC_TO_TIME(SUM(time_difference)),'%i') as time_spent 
better 
SELECT user_id, TIME_FORMAT(SEC_TO_TIME(SUM(time_difference)),'%Hh %im') as time_spent 

要獲得一個USER_ID的time_spent,您可以添加

JOIN(SELECT @DIS:= 0)R)TAB1 WHERE user_id = 1

SQL FIDDLE隨時間轉化率和其中USER_IDhttp://sqlfiddle.com/#!2/ab988/9

+0

如果一個用戶在另一個用戶的操作之間執行操作,該怎麼辦? –

+0

這是不相關的(我認爲),因爲計算只是執行,'當user_id是相同的',它是'user_id分組。換句話說:時間計算是按用戶完成的。 –

+0

「不相關」是什麼意思?你是說這些記錄不相關?我的猜測是OP會不同意。所以假設'id/user_id/action/time',假設我們有行'1/1/1/12:00:00','2/2/1/12:05:00'和'3/1/2/12:10:00'。第一個和最後一個ID之間的差值大於1,但是仍應計算動作次數之間的差異。 –