我有这个表,包含某些日期的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
确保某处有一个结束,因为可能有一个“开放”结束)
有人知道如何解决这个问题吗?
答案 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);
}