【问题标题】:Struggling with logic for checking consecutive data entries努力检查连续数据条目的逻辑
【发布时间】:2010-12-22 18:41:25
【问题描述】:

我正试图弄清楚如何处理我今天早上发现自己遇到的一个棘手的小情况。我的数据库中有一个条目表,我在其中存储有关用户每月条目的详细信息(信息捕获内容) - 我想在一个月过去后增加每个条目的数量(而不是 ID)。这个想法是使用“数字”字段来识别连续的每月条目并忽略彼此靠近的条目。

当用户访问该站点以开始新条目时,我会检查最后一个条目的完成日期,看它是否超过 21 天前(这符合有效月份的条件),然后我增加“数字”对于这个新条目。问题是我最终会得到一系列相隔不到 21 天的条目(因此它们都具有相同的数字),但总共跨越 21 天以上!我需要能够找到一些逻辑来处理这个问题 - 有人有什么想法吗?

如何存储这些数据的示例以及我遇到的问题如下所示。

+------+--------+------------+------------+----------------------------+
| id   | number | initiated  | updated    | last_category_reached      |
+------+--------+------------+------------+----------------------------+
|    4 |      1 | 1277914181 | 1277914320 | complete                   |
|  105 |      2 | 1282639343 | 1283444717 | complete                   |
|  397 |      3 | 1284999429 | 1285001298 | complete                   |
|  404 |      3 | 1287478550 | 1287478631 | complete                   |
|  636 |      3 | 1287479243 | 1287479377 | complete                   |
|  649 |      3 | 1287581361 | 1287581466 | complete                   |
|  652 |      3 | 1287585123 | 1287585365 | complete                   |
|  656 |      3 | 1290185205 | 1290424128 | complete                   |
| 1105 |      3 | 1292421193 | 1292426686 | complete                   |
| 1106 |      3 | 1292426769 | 1292426870 | complete                   |
+------+--------+------------+------------+----------------------------+

我的php逻辑如下...

public function update_entry($stage = NULL)
    {
        // Get last number entered for this user
        $last_entry = $this->last_entry();

        // If part one, user profile is calling the update (passing the next stage as a param)
        if ($stage === 'user/profile/2?s=p_prof&p=2')
        {
            // Only at this stage do we ever create a new entry
            $entry = ORM::factory('data_entry');

            // If no previous sessions, start from 1
            if ($last_entry === FALSE)
                $num = 1; 

            //Here we need to check the time period elapsed since the last submission
            else
            {
                // Check if time difference between last visit and current time is less than 49 days and more than 21 days
                if (($last_entry->initiated > time() - 4233600) && ($last_entry->initiated < time() - 1814400))
                {
                    // Within allowed timeframe, ok to increment by one as a new entry
                    $num = $last_entry->number + 1;
                }
                // More than 49 days since last visit
                elseif (($last_entry->initiated < time() - 4233600)) 
                {
                    // Increment by two to break consecutive entries
                    $num = $last_entry->number + 2;
                }
                // Entry is within the last 21 days - if user never finished stages, use last entry created instead of creating a new one
                else
                {
                    // If they are back at the start having completed a full entry the last time, ok to create a new entry - otherwise use the one created the last time
                    if ($last_entry->last_category_reached !== 'complete')
                        $entry = $last_entry;

                    $num = $last_entry->number;
                }

            }

            // Save the rest of the data for a new entry
            $entry->number = $num;
            $entry->initiated = time();
            $entry->updated = time();
            $entry->last_category_reached = $stage;
            $entry->user_id = $this->id;
            $entry->save();
        }
        // If it's been more than 49 days since last part completion of an entry, user won't be given option to finish the entry, so no need for time check here
        elseif ($stage !== NULL)
        {
            // This must be a continuation of a form, not the beginning of a new one
            // Just update the stage reached and save
            $last_entry->last_category_reached = $stage;
            $last_entry->updated = time();
            $last_entry->save();
            // Assign to $entry for return
            $entry = $last_entry;
        }

        return $entry;
    }

    /**
     * Returns the the last data entry session
     * @return 
     */
    public function last_entry()
    {
            return $this
                    ->limit(1)
                    ->data_entries
                    ->current();
    }

【问题讨论】:

  • 用 4233600 增加你的时间戳不会考虑到夏令时的变化,试试time() - (time() - strtotime('- 49 days'))
  • 这有点太抽象了。正确的逻辑取决于我们没有关于此应用程序真正业务需求的信息。原始目标与您提出的解决方案之间可能存在很大的脱节,我们无法衡量,以便了解基于您当前方案的建议是否符合要求或偏离得更远。如果您强迫我提出一个想法,那就是唯一标识条目组,而不是重复使用递增的数字。确定最新条目是否应属于最后一组。
  • 谢谢丹,你是对的 - 很难简明地解释!我认为@LaGrandMere 已经根据我当前的设置提出了我正在寻找的内容

标签: php


【解决方案1】:

我会用伪代码做什么:

如果有前一个数字,则取带有 max(number) 和 min(id) 的条目。 计算此条目的时间与当前时间之间的延迟。 21天以内不换号,超过21天就换号。

如果你应用这个,你不会得到持续超过 21 天的月经。

【讨论】:

  • 谢谢,这就是我要找的东西——今天早上大脑没有工作!使用 max(number) 和 min(id) 浪费了一些时间进行内部连接,然后意识到我只需要使用 order by number desc, id asc limit 1 进行查询
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多