1

我知道这个很奇怪。我有一个称为schedule列的表Date,列类型为DATE. 我在本专栏中有从 2012-11-01 到 2013-01-02 的日期(格式为 YYYY-MM-DD)。发生的事情是,如果我输入一个日期,任何日期,其间有 2012-12-01,它会重新启动循环。因此,如果我选择 2012-11-15 到 2012-12-15,它将在 11 月 15 日到 12 月 1 日打印,但在 12 月 1 日之后,它会在 11 月 15 日再次开始打印。如果我选择 2012-11-15 到 2012-11-30 或 2012-12-02 到 2012-12-30 一切正常,只是当涉及到该特定日期时才会出现问题。这是我的代码:

<?php
////////////////////////////////////////////////////////
//////First set the date range that we want to use//////
////////////////////////////////////////////////////////

if(isset($_POST['from']) && ($_POST['from'] != NULL))
    {
    $startDate = $_POST['from'];
    echo "<script>alert (\"startDate: " . $startDate . "\")</script>";
    }
else
    {
    //Default date is Today
    $startDate = date("Y-m-d");
    echo "<script>alert (\"startDate: " . $startDate . "\")</script>";
    }
if(isset($_POST['to']) && ($_POST['to'] != NULL))
    {
    $endDate = $_POST['to'];
    echo "<script>alert (\"endDate: " . $endDate . "\")</script>";
    }
else
    {
    //Default day is one month from today
    $endDate = date("Y-m-d", strtotime("+1 month"));
    echo "<script>alert (\"endDate: " . $endDate . "\")</script>";
    }

//////////////////////////////////////////////////////////////////////////////////////
//////Next calculate the total amount of days selected above to use as a limiter//////
//////////////////////////////////////////////////////////////////////////////////////

    $dayStart = strtotime($startDate);
    $dayEnd = strtotime($endDate);
    $total_days = abs($dayEnd - $dayStart) / 86400 +1;
    echo "<script>alert (\"Total Days: " . $total_days . "\")</script>";

//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////Then we're going to get the date range specified from the schedule table and print the results//////
//////////////////////////////////////////////////////////////////////////////////////////////////////////

//Select the dates from the schedule table, limited to the total amount days.
$sql = ("SELECT Date FROM schedule WHERE Date BETWEEN '$startDate' AND '$endDate' LIMIT $total_days");

//Run a check on the query to make sure it worked. If it failed then print the error.
if(!$result_date_query = $mysqli->query($sql))
    {
    die('There was an error getting the date from the schedule table [' . $mysqli->error . ']');
    }

//Loop through the results while a result is being returned.
while($row = $result_date_query->fetch_assoc())
    {
    //First format and then print the all the dates selected.
    echo "<td class=\"schedule_date_cell\">" . date('M j', strtotime($row['Date'])) . "</td>";
    }

//Free the result.
$result_date_query->free();
?>

我很茫然。我添加了一些 echo 语句来显示正在发生的事情以及一切都按预期进行。我只是不明白之前的所有日期和之后的所有日期是如何完美地工作的,但是其中包含 12 月 1 日的任何内容都会使其重新启动循环。我不确定它是否相关,但列中有多个相同日期,这就是我LIMIT在查询中设置的原因。

我希望有人能打开这个案子,因为我很想知道答案!

**编辑:**我按照评论中的建议在 PHPmyadmin 中尝试了相同的查询,它产生了相同的结果。我还尝试删除LIMIT以及从单引号更改'2012-11-01'为双引号"2012-11-01",结果仍然相同。

**EDIT2:**对于Date列中的每个日期,每个日期有 92 个实例。因此,例如,有 2012-12-01 的 92 条记录和 2012-12-02 的 92 条记录,依此类推。有趣的是,当我LIMIT从查询中删除并使用 2012-11-30 到 2012-12-15(11 月 30 日到 12 月 15 日)的日期范围时,会打印 11 月 29 日、11 月 30 日、12 月 1 日然后重复这三个日期一次又一次,92次!然后,它开始打印 12 月 2 日、12 月 3 日、12 月 4 日……12 月 15 日剩下的日子,然后一次又一次地重复这些日期,92 次!这只是证明由于某种原因循环在 12 月 1 日重新开始,因为如果我输入 11 月 1 日到 11 月 3 日的日期范围,它会在重复 92 次之前打印该范围内的所有日期。的原因LIMIT是为了阻止它返回每个日期的所有实例,所以我只会得到 11 月 1 日到 11 月 3 日一次,而不是 92 次,但是当限制被删除时,我们可以看到 12 月 1 日引起了一些奇怪的问题。

**EDIT3:**我创建了一个与 2012-11-01 到 2013-01-02schedule2相同的新表schedule并输入了相同的日期范围,但这次只有一个实例。然后我再次运行我的查询,它可以在任何日期组合中完美运行。很明显,问题是表中有不止一个该日期的实例schedule,但我不知道为什么会出现问题。我不明白这个日期对while循环有什么影响。在你提出建议之前,是的,我确实需要在表格中有多个相同日期的实例;)

4

3 回答 3

2

没有必要使用LIMIT从句。相反,更改您的查询以确保它不会多次返回任何日期:

SELECT DISTINCT(Date) FROM schedule WHERE Date BETWEEN '$startDate' AND '$endDate'

这会给你每个约会一次。

您可能在该Date列上有一个索引(这很好),并且该索引将 11 月的所有日期排在 12 月的日期之前(至少在同一年)。对于从 12 月开始到 1 月结束的日期范围,您也会遇到同样的问题。

于 2012-11-23T06:50:33.127 回答
1

它在 12 月 1 日循环播放的事实在很大程度上只是一个巧合。我不知道 MySQL 内部如何工作的细节,但如果你不给它一个命令,那么它会在你请求数据时应用它感觉的任何顺序。

将此与您有重复日期的事实相结合,然后您最终会遇到您所描述的无缘无故自发发生的情况。

由于您希望每个日期恰好出现一次,并且您希望它们按时间顺序出现,那么您需要在查询时告诉 MySQL 您想要这两件事。因此,添加DISTINCTANDORDER BY命令:

SELECT DISTINCT(Date) FROM schedule WHERE Date BETWEEN '$startDate' AND '$endDate' ORDER BY Date ASC
于 2012-11-23T18:26:01.410 回答
0

您可以通过UNIQUE在定义特定日期的条目的列上添加索引来防止重复。

如果您已经清理了数据以删除重复项,那么这很容易在事后添加:

ALTER TABLE schedule ADD UNIQUE INDEX index_on_date (date)

另一种方法是每个日期只选择一行,这通常相当于GROUP BY date在查询末尾追加。

于 2012-11-23T06:38:23.113 回答