2016-06-16 2 views
2

안녕하세요. mySQL 데이터베이스에서 시작/중지 행 2 개 사이의 시간을 가져올 수 있습니다. 내 표는 다음과 같습니다.PHP mySQL 시간 간격 행

fillercdown_ndx | time     | B3_4_5 
1    | 2016-06-16 14:59:45 | 0 
2    | 2016-06-16 15:03:11 | 1 

기본적으로 0으로 기록 될 때 기계가 중지되고 기록이 1이면 기계가 다시 시작됩니다. 저는 기계가 오전 8 시부 터 오후 5 시까 지와 같은 특정 시간 사이에 시간의 양을 계산할 수 있어야합니다. 입력 한 시간에 PHP를 사용하여 표시 할 것이지만 SQL 명령에 대해서는 알지 못합니다.

누구나 가장 쉽게 찾을 수 있습니다.

테이블을 작성

CREATE TABLE `fillercdown` (
`fillercdown_ndx` int(11) NOT NULL AUTO_INCREMENT, 
`time` datetime DEFAULT NULL, 
`B3_4_5` int(11) DEFAULT NULL, 
PRIMARY KEY (`fillercdown_ndx`), 
KEY `fillercdowntimendx` (`time`) 
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 

UPDATE :

이 "중지" "시작"항목의 수백있을 것입니다. 내 목표는 모든 목표는 사용자에게 8 AM-5PM과 같은 시간 범위를 제공하도록 요청한 작은 양식을 제공 한 다음 기계가 "정지 된"모든 시간을 계산할 수있게하는 것입니다 (이는 B3_4_5가 0 일 때입니다).). 난 그냥 각각의 0과 1 사이의 시간 차이를 얻고 설정 시간 범위 사이에 그들을 추가 할 수있는 올바른 SQL 호출을 알아낼 수없는 것 같습니다

+0

: 당신은 format 방법을 사용하여 메시지를 반환받을 수 있나요? 또한 : a) 특정 '0'에서 다음에 '1'이 나타날 때까지의 지속 시간을 알고 싶습니까? 즉, 'fillercdown_ndx'를 알고 계십니까? b) 모두로부터? c) 평균? – Centril

+0

업데이트 됨 자세한 내용을 확인하시기 바랍니다. 미안 나는 아직도 정말로 배우고있다. 그러나 최선을 다해 노력하고있다. 이것은 막 붙어 있습니다. –

+0

질문을 올바르게 이해하면 X와 Y 시간 내에 (0,1)의 모든 쌍을 선택하고 그 간격의 합을 계산하고 싶습니까? – Centril

답변

0

이것은 기본적인 아이디어입니다 ... 그것은 단일 row and, which you can then fetch with PHP` ...

이 솔루션은, 즉 & 시작이 쌍으로 중지하는 가정은 : 시작의 ​​ID는 정지의 +1 될 것입니다. 그렇지 않은 경우 의 ID는 >이며 중지 된 ID는 LIMIT입니다. 1입니다.

자체 조인은 최적의 성능을 낼 수 없으므로 일부 데이터가 안전한쪽에 있도록주의해서 실행 시간을 측정하십시오. 당신은 기계가 정지 아직 다시 시작하지 않은 시간을 포함 할 경우

http://sqlfiddle.com/#!9/de72bf/1

CREATE TABLE fillercdown (
`fillercdown_ndx` int(11) NOT NULL AUTO_INCREMENT, 
`time` datetime DEFAULT NULL, 
`B3_4_5` int(11) DEFAULT NULL, 
    PRIMARY KEY (`fillercdown_ndx`), 
    KEY `fillercdowntimendx` (`time`) 
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; 

INSERT INTO fillercdown 
    (`time`, `B3_4_5`) 
VALUES 
    ('2016-06-16 14:00:45', 0), 
    ('2016-06-16 14:01:00', 1), 
    ('2016-06-16 16:00:00', 0), 
    ('2016-06-16 16:01:00', 1) 
    ; 

SELECT SUM(TIMEDIFF(g.`time`, f.`time`)) 
FROM fillercdown f 
INNER JOIN fillercdown g 
    ON g.`fillercdown_ndx` = (f.`fillercdown_ndx` + 1) 
    AND g.`B3_4_5` = 1 
    AND TIME(g.`time`) BETWEEN '08:00:00' AND '17:00:00' 
WHERE f.`B3_4_5` = 0 
    AND TIME(f.`time`) BETWEEN '08:00:00' AND '17:00:00' 

, 당신은 같은 것을 할 수 있습니다

http://sqlfiddle.com/#!9/d113b9/9

INSERT INTO fillercdown 
    (`time`, `B3_4_5`) 
VALUES 
    ('2016-06-16 14:00:45', 0), 
    ('2016-06-16 14:01:00', 1), 
    ('2016-06-16 16:00:00', 0), 
    ('2016-06-16 16:01:00', 1), 
    ('2016-06-16 16:02:00', 0) 
    ; 

SELECT SUM(TIMEDIFF(COALESCE(g.`time`, '2016-06-16 16:02:01'), f.`time`)) 
FROM fillercdown f 
LEFT JOIN fillercdown g 
ON g.`fillercdown_ndx` = (f.`fillercdown_ndx` + 1) 
    AND g.`B3_4_5` = 1 
    AND TIME(g.`time`) BETWEEN '08:00:00' AND '17:00:00' 
WHERE TIME(f.`time`) BETWEEN '08:00:00' AND '17:00:00' AND f.`B3_4_5` = 0 

당신은 대체 할 수 과 NOW() 또는 f.time을 기반으로 한 값은 물론 응용 프로그램이 필요합니다.

NULL을 절대 받고 싶지 않고 0을 얻으려면 일치하는 행이없는 경우 COALESCE(SUM(...), 0)과 같이하십시오.

SELECT f.`time`, f.`B3_4_5` 
FROM fillercdown f 
WHERE TIME(f.`time`) BETWEEN '08:00:00' AND '17:00:00' 

을 그리고 그렇게 (psuedocode) 같은 합계를 계산 : 당신이 스크립트 솔루션을 선호하는 경우

당신은 항상 이런 식으로 뭔가를 할 수

stopped = null; 
pairs = [] 
for (row in rows) 
    if (row.isStopped) stopped = row 
    else 
     pairs += [stopped, row] 
     stopped = null 

sum = 0 
for (pair in pairs) 
    sum += duration(pair[0], pair[1]) 
+0

당신은 어쩌면 어딘가에서 가장 훌륭하고 가장 큰 것을 원할지도 모릅니다 – Strawberry

+0

@Strawberry는 그것에 대해 자세히 설명합니다, 어디에서? 일치하는 항목이없는 경우 null이 아닌 결과를 만들려면? – Centril

+0

또한 개선 할 수 있다면 답을 편집하십시오. =) – Centril

0

이 내가 현재 나는 무엇인가 당신이하려고하는 것처럼 들리는 똑같은 일을하기 위해 사용합니다.저는 PDO를 사용하고 있습니다 만, 이것을 사용하려면 mysqli에 대해 상당히 쉽게 적응할 수 있습니다. 이것은 시간에 따라 off/on 값을 번갈아 사용하는 것에 달려 있습니다. 어떤 이유로 든 연속적인 행 또는 열이있는 경우 예상되는 결과가 모호 해집니다.

// First select everything in the requested range ordered by time. 
$sql = "SELECT `time`, B3_4_5 FROM your_table WHERE `time` BETWEEN ? AND ? ORDER BY `time`"; 
$stmt = $pdo->prepare($sql); 
$stmt->execute([$query_start, $query_end]); 

// Initialize two DateTime objects (start and end) used to calculate the total time. 
$total_start = new DateTime('00:00'); 
$total_end = clone $total_start; 

$off = null; 
while ($row = $stmt->fetchObject()) { 
    if ($row->B3_4_5) { 
     $on = new DateTime($row->time); 
     // increment total end time with difference between current off/on times 
     if ($off) { 
      $total_end->add($on->diff($off)); 
     } 
    } else { 
     $off = new DateTime($row->time); 
    } 
} 

// total downtime is difference between start and end DateTimes 
$total_downtime = $total_start->diff($total_end); 

$total_downtimeDateInterval 개체입니다. 당신은이`질문에이 테이블에 대한 TABLE`를 만들 추가 할 수 있습니다 ... 나는`fillercdown_ndx`가 기본 키입니다 있으리라 믿고있어

echo $total_downtime->format('Total downtime: %h hours, %i minutes, %s seconds.'); 
+0

고맙습니다! 나에게 좋은 방향을 제시하고 적합하도록 수정 작업을 할 수 있습니다. –