【问题标题】:How to fetch previous month's data from database in php?如何在php中从数据库中获取上个月的数据?
【发布时间】:2014-05-15 22:29:25
【问题描述】:

我正在开发一个 php 网站,需要从上个月获取一些数据。不仅是前一个月的数据,还有最近五个月的数据。我很困惑,我该怎么做?在我的数据库中,我创建了两列。一个是“月”,另一个是“年”。所以行看起来像


id ---- 文本 ---- 月 ---- 年

1 ---- 你好 ---- 2014 年 5 月

2 ---- 嗨 ---- 5 月 ----- 2014 年


现在我可以像这样使用 date() 函数来获取数据了。

$first_month = date('F', strtotime('-1 month'));
$second_month = date('F', strtotime('-2 month'));
$third_month = date('F', strtotime('-3 month'));

五个月,我可以创建五个变量。但是一年呢?我的意思是如果当前月份是 2014 年 1 月和 2014 年,那么我需要从 2013 年 12 月获取数据,那么它将如何工作?任何人都可以建议我吗?

我很困惑。请告诉我是否有人以前做过这样的事情。我需要想法或概念。

【问题讨论】:

  • 致未来的探索者。这打破了惯例,并且不允许使用本机包装器和辅助函数,例如简单的SELECTS、更改时区和排序。强烈建议不要这样做。使用 MySQL 自带的类型date,省去很多麻烦。

标签: php date mysqli


【解决方案1】:

您可以重组表以使用 Unix 时间戳或 MySQL date,并使用比较器进行选择。或者您可以创建临时表并执行相同的操作。

您前进的方向对于维护和调试来说将是非常重要的。此外,正确的查询将比我相信的更复杂。例如,跨越年份将与上述一致。虽然许多线路都按照您的方式进行。

编辑:为了保持您当前的逻辑,SQL Select 语句必须是一系列WHEREs。例如:

SELECT * FROM table
WHERE
    (month IN ('April', 'May') AND year = 2014)

将选择 2014 年的 4 月和 5 月。

以下将跨越一年:

SELECT * FROM table
WHERE
    (month IN ('December') AND year = 2013)
OR
    (month IN ('January') AND year = 2014)

从程序化的角度来看,您需要生成一系列年份和月份,包括您希望从中选择的一年中的所有月份。

这样一个数组的结构如下所示:

// For the first example
$where1 = array(
    2014 => array(
        'April',
        'May'
    )
);

// For the second example
$where2 = array(
    2013 => array(
        'December'
    ),
    2014 => array(
        'January'
    )
);

您必须从这些数组中创建一个WHERE 子句。如:

/**
 * Outputs
 * [where1] (month IN ('April', 'May') AND year = 2014)
 *
 * [where2] (month IN ('December') AND year = 2013) OR (month IN ('January') AND year = 2014)
 */
foreach(array('where1','where1') as $where_name) {

    $clause = '';

    $where = $$where_name;

    $wheres = array();

    foreach($where as $year => $months) {
        $wheres[] = "month IN ('" . implode("', '", $months) . "') AND year = $year";
    }

    $clause = '('.implode (') OR (', $wheres).')';

    echo "[$where_name] $clause\n\n";
}

这应该可以解决问题。有一个工作示例here。收集月份列表几乎和你一直在做的一样,但更像是这样:

    list($month, $year) = explode(" ", date('F Y', strtotime('-3 month')));

var_dump($month); // February
var_dump($year); // 2014

$array[$year][] = $month; // Will create the array structure as above

有更有效的方法,但这是一般的想法。我相信我给你留下了一些有趣的工具来解决你的问题。

要使其达到一个范围,您需要执行以下操作:

$where3 = array();

for ($prev_months = 1; $prev_months <= 5; $prev_months++) {
    list($month, $year) = explode(" ", date('F Y', strtotime("-$prev_months month")));
    $where3[$year][] = $month;
}

您可以在此处查看工作示例: http://ideone.com/UWI5wI

作为参考,以下是使用您的方法与公认规范的示例:

// your last and 5
(month IN ('April', 'March', 'February', 'January') AND year = 2014) OR (month IN ('December') AND year = 2013)

// native 1 and 5
date <= 2014-05-01 01:00:00 AND date > 2013-12-01 01:00:00

我使用第一个(这不是惯例),因为每个月都有一个第一个。您可能希望使用目标月份的最后一天,而不是下个月的第一天,但​​您明白了。

当跨越很长一段时间时,差异会更加明显:

// 2 years, yours
(month IN ('April', 'March', 'February', 'January') AND year = 2014) OR (month IN ('December', 'November', 'October', 'September', 'August', 'July', 'June', 'May', 'April', 'March', 'February', 'January') AND year = 2013) OR (month IN ('December', 'November', 'October', 'September', 'August', 'July', 'June', 'May') AND year = 2012)

// The conventional way is still just two comparators...

【讨论】:

  • 是的,我知道这就是我寻求建议的原因。
  • 你让我为此工作。我确定我刚刚解决了你的作业或其他问题,但这是一个需要解决的小问题。所以,尽管如此,“谢谢。”
【解决方案2】:

MySQL 日期格式为 YYYY-MM-DD HH:MM:SS

或(获取一个月前的日期格式):

date("Y-m-d H:i:s",strtotime("-1 month"));

您应该在新数据上发布一个已创建的(时间戳/日期时间)列,并简单地搜索这些数据。

通过创建月、日、年列并尝试将它们分开只会让您自己更难。

【讨论】:

  • 很好的观察,这就是为什么我说他应该使用日期格式:p 以 OP 的方式分离列简直是可怕的做法。为了解决这种糟糕的架构,您必须编写大量代码。
  • 确实如此,但是TBH,我发现它有点有趣。就像从栏杆之间拉人头一样有趣。你不应该这样做,你会强烈建议不要这样做。但是打败它的满足感……嗯,有点值得。
  • 哈哈触摸。我会说你的回答给我留下了深刻的印象:p 事实上我给你投了赞成票。
  • 你想知道真相吗?我每天都在使用一个框架,它做的事情与上面的不太一样。与dates 无关,但它让我非常擅长在程序上创建复杂的SELECT 语句以处理其他琐碎的事情。保持心脏跳动。
【解决方案3】:

如果你想保持你的表结构,你可以使用你所拥有的:

$month = date('F', strtotime('-6 month'));
$year = date('Y', strtotime('-6 month'));

将在 11 月和 2013 年为您提供

不确定您存储的是什么类型的数据,但另一种选择可能是根据年份命名您的表,然后每个月都有列

表名:year_2014

 id----m1---m2---m3 etc...
 1----hello
 2----hi
 3----Hey

那么您的查询将是:

$month = date("n", strtotime('-6 month'));
$year = date('Y', strtotime('-6 month'));
$monthval = "m" + $month;
$SQL = "SELECT " . $monthval . " FROM year_".$year;

SELECT m11 FROM year_2013

【讨论】:

  • 什么?请注意,考虑到您引用的是不存在的表以及列,请确保它会像您认为的那样工作......
  • 为什么这些表等...不存在,因为他会创建它们?
  • OP已经提供了表结构,有没有看到名字为m11的列,每年创建一个新表(FROM year_2013)有意义吗?此外,您的示例不仅需要每年一个新表,还需要 12 列,用于...单个字符串。需要过滤NULL 返回等。这不切实际。如果 OP 可以随意修改表结构,最理想的解决方案是使用 MySQL date 或 Unix Timestamp。但他们出于自己的原因不愿意这样做。
  • 但他也在寻求想法和概念,就是这样。
  • 我并没有粗鲁的意思,只是坦率地说:“从数据完整性的角度来看,这是不稳定的。从数据存储的角度来看,这是低效的(取决于列类型)和不灵活的(仅每月一串数据[如果 OP 需要更多数据,比如作者、标签等怎么办?])。从约定的角度来看,我从未见过使用过。从可用性的角度来看,这很难管理和调试(由于到前面的陈述)。”这是一个想法,它是。
猜你喜欢
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-03
  • 1970-01-01
相关资源
最近更新 更多