0

22:38のような出力を取得するために、複数のレコードの平均 SUM 時間(datetime フィールドから取得) をmysql にクエリしようとしています。

私の日時フィールド checkin_time には、次のようなデータが含まれています。

2012-03-16 22:48:00 // the time here: 22:48 is what's interesting to me
2012-03-16 02:28:32
2012-03-16 00:28:47
0000-00-00 00:00:00

私の計画は、すべての日時フィールドから合計時間を抽出して選択し、合計を UNIX タイムスタンプに変換し、合計をレコードの総数で割り、最後に時間形式に戻すことでした。ただし、これ(以下のコードを参照)は何も得られず、エラーも何もありません。また、0000-00-00 00:00:00 のような空のフィールドは、関連するデータを生成するために考慮されるべきではないことに気付きました。

間違いを指摘したり、あなたがそれを行う方法の背後にある理論を説明したりするのを手伝ってくれる人はいますか? これは私がこれまでに得たものです:

編集:動作する SQL クエリを提案してくれたDamiqibに感謝しますが、まだ完全には正しくありません。以下のコードは、23:15になるはずの01:00を出力します。

 $getCheckinTime = mysql_query("SELECT COUNT(id), SEC_TO_TIME( AVG( TIME_TO_SEC(  `checkin_time` ) ) ) AS averageTime FROM guests WHERE checkin_time != '0000-00-00 00:00:00'") or die(mysql_error());
while($checkIn = mysql_fetch_array($getCheckinTime)) { 

    $timestamp = strtotime($checkIn['averageTime']);
    $UnixTimeStamp = date("Y-m-d H:i:s", $timestamp); //converting to unix
    $avgUnix = $UnixTimeStamp / $checkIn['COUNT(id)']; // calculating average
    $avgTime = date('H:i', $avgUnix); // convert back to time his format
    echo $avgTime; //outputs 01:00, got to be incorrect should be 23:15 something

}

前もって感謝します

編集:解決策(Damiqibに感謝):

$avgCheckinTime = array();
$getCheckinTime = mysql_query("SELECT TIME(`checkin_time`) AS averageTime    FROM guests    WHERE checkin_time !=  '0000-00-00 00:00:00'") or die(mysql_error());
while($checkIn = mysql_fetch_array($getCheckinTime)) { 

    array_push($avgCheckinTime, $checkIn['averageTime']);
}

// = array('22:00:00', '22:30:00'...)
    $times = $avgCheckinTime;

    $fromReplace = array('22' => '00',
                   '23' => '01',
                   '00' => '02',
                   '01' => '03',
                   '02' => '04',
                   '03' => '05',
                   '04' => '06',
                   '05' => '07');

  $timeSum = 0;

  //Iterate through all given times and convert them to seconds
  foreach ($times as $time) {
   if (preg_match ('#^(?<hours>[\d]{2}):(?<mins>[\d]{2}):(?<secs>[\d]{2})$#',$time, $parse)) {
  $timeSum += (int) $fromReplace[$parse['hours']] * 3600 + (int) $parse['mins'] * 60 + (int) $parse['secs'] . '<br />';

  //echo $time . ' ' . ($fromReplace[$parse['hours']] *3600) .  '<br />'; 
  }
}

   $toReplace = array('00' => '22',
                 '01' => '23',
                 '02' => '00',
                 '03' => '01',
                 '04' => '02',
                 '05' => '03',
                 '06' => '04',
                 '07' => '05');

 $time = explode(':', gmdate("H:i:s", $timeSum / count($times)));

 $averageCheckinTime = $toReplace[$time[0]] . ':' . $time[1] . ':' . $time[2];

 //This is the final average time biased between 22-05
 echo $averageCheckinTime;
4

1 に答える 1

1

これは私のテストデータでうまくいくようでした:

SELECT SEC_TO_TIME(AVG(TIME_TO_SEC(`time`))) AS averageTime
FROM guests 
WHERE checkin_time != '0000-00-00 00:00:00'

アップデート:

-- Table structure for table `guests`
CREATE TABLE `guests` (
  `checkin_time` datetime NOT NULL,
  KEY `checkin_time` (`checkin_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- Dumping data for table `guests`
INSERT INTO `guests` VALUES('2012-08-17 17:30:00');
INSERT INTO `guests` VALUES('2012-08-17 18:30:00');
INSERT INTO `guests` VALUES('2012-08-17 19:30:00');
INSERT INTO `guests` VALUES('2012-08-17 20:30:00');
INSERT INTO `guests` VALUES('2012-08-17 21:30:00');


Showing rows 0 - 0 (1 total, Query took 0.0003 sec)
SELECT SEC_TO_TIME( AVG( TIME_TO_SEC(  `checkin_time` ) ) ) AS averageTime
FROM guests
WHERE checkin_time !=  '0000-00-00 00:00:00'
LIMIT 0 , 30

結果

averageTime
19:30:00

少なくとも私のテストデータでは、これは機能しているようですか?

別の更新

<?php

  /*
    SELECT TIME(`checkin_time`) AS averageTime
    FROM guests
    WHERE checkin_time !=  '0000-00-00 00:00:00'
  */

  // = array('22:00:00', '22:30:00'...)
  $times = RESULT_FROM_QUERY_AS_AN_ARRAY_OF_TIMES;

  $fromReplace = array('22' => '00',
                       '23' => '01',
                       '00' => '02',
                       '01' => '03',
                       '02' => '04',
                       '03' => '05',
                       '04' => '06',
                       '05' => '07');

  $timeSum = 0;

  //Iterate through all given times and convert them to seconds
  foreach ($times as $time) {
    if (preg_match ('#^(?<hours>[\d]{2}):(?<mins>[\d]{2}):(?<secs>[\d]{2})$#',$time, $parse)) {
      $timeSum += (int) $fromReplace[$parse['hours']] * 3600 + (int) $parse['mins'] * 60 + (int) $parse['secs'] . '<br />';

      echo $time . ' ' . ($fromReplace[$parse['hours']] *3600) .  '<br />'; 
    }
  }

  $toReplace = array('00' => '22',
                     '01' => '23',
                     '02' => '00',
                     '03' => '01',
                     '04' => '02',
                     '05' => '03',
                     '06' => '04',
                     '07' => '05');

  $time = explode(':', gmdate("H:i:s", $timeSum / count($times)));

  $averageCheckinTime = $toReplace[$time[0]] . ':' . $time[1] . ':' . $time[2];

  //This is the final average time biased between 22-05
  echo $averageCheckinTime;   

?>
于 2012-08-16T23:48:22.853 に答える