从表中获取同一组的连续日期

时间:2017-12-12 13:34:19

标签: php mysql

我有这个表,包含某些日期的group_id:

date       | group_id
2017-12-12 | 1
2017-12-14 | 1
2017-12-15 | 1
2017-12-16 | 9
2017-12-17 | 9
2017-12-24 | 1

备注:每个日期都不在表格中;对于不存在的日期,存在“默认”值。

问题:
给定日期$date:将来连续几天$n具有相同的group_id值? (不包括指定日期)

在上表中,使用$default = 1,结果如下:

2017-12-12: 3 (13-default, 14 & 15)
2017-12-16: 1 (17)

脚手架:

function getConsecutiveDays($date, $default = 1, $max = 99)
{

   //magic

   return $n;
}

(使用$max确保某处有一个结束,因为可能有一个“开放”结束)

有人知道如何解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

这是一种非常直接但并非完全有效的方法;但它应该澄清这个想法。

它也主要使用伪代码和不存在的方法,希望能够清楚地表明它们的作用......

function getConsecutiveDays(\DateTimeInterface $date, $default = 1, $max = 99)
{       
   $initialGroup = findGroupForDate($date);
   $date = $date->modify('+1 days');
   $n = 1;

   while( $n < $max ) {
     $groupOnDate = findGroupForDate($date);
     // default check
     if($groupOnDate === null) {
       $groupOnDate = $default;
     }
     // if this is a different group; no longer consecutive
     if($groupOnDate !== $initialGroup) {
       return $n;
     }
     // count as consecutive
     $n++;
     $date = $date->modify('+1 days');
   }   
   return $n;
}

function findGroupForDate(\DateTimeInterface $date) {
  $rows = query("select group_id from some_table where date = " . $date->format('Y-m-d'));
  if(count($rows) == 0) {
    return NULL;
  }
  return $rows[0]['group_id'];
}

答案 1 :(得分:1)

以Erik的答案为基础,但只使用一个数据库查询:

props.value

输出:

function getConsecutiveDays($date, $default = 1, $max = 99)
{
    $date = DateTime::createFromFormat('Y-m-d', $date);
    $results = getConsecutiveDaysFromDatabase($date, $max);
    $result = reset($results);
    $initial_group_id = false;
    $n = 0;
    while ($max--)  {
        $day = $date->format('Y-m-d');
        if ($result && $result->date === $day) {
            $group_id = (int) $result->group_id;
            $result = next($results);
        } else {
            $group_id = (int) $default;
        }
        if (!$initial_group_id) {
            $initial_group_id = $group_id;
        } elseif ($initial_group_id === $group_id) {
            $n++;
        } else {
            break;
        }
        $date->add(new DateInterval('P1D'));
    }
    return $n;
}

function getConsecutiveDaysFromDatabase(DateTimeInterface $date, $max = 99)
{
    $database = new PDO(/* your connection details here */);
    $statement = $database->prepare('
        SELECT date, group_id
        FROM some_table
        WHERE date >= :date
        ORDER BY date ASC
        LIMIT :max;
    ');
    $statement->bindValue(':date', $date->format('Y-m-d'), PDO::PARAM_STR);
    $statement->bindValue(':max', (int) $max, PDO::PARAM_INT);
    $statement->execute();
    return $statement->fetchAll(PDO::FETCH_OBJ);
}