【问题标题】:Selecting data from a period of full months based on the current date根据当前日期从整月期间选择数据
【发布时间】:2014-11-02 18:45:37
【问题描述】:

我最近的任务是编写一个报告工具来获取一些历史数据。 但我到了一个我被困住的地步。我无法获取过去整月的数据。

故事: 用户得到一个字段,他可以在其中键入他想要获取历史(过去几个月的)多长时间,例如:我想要最近 3 个月的数据。他输入他的值,发送数据并(应该)得到这样的输出(因为我们现在有九月):

X data in August,
Y data in July,
Z data in June.

我的查询是:

SELECT * FROM table WHERE (publish_up between date_sub(NOW(), 
INTERVAL ".$history." MONTH)
AND date_sub(now(), INTERVAL " . -- $history . " MONTH))
AND created_by = '$editorID' AND state = 1 AND sectionid in (1,2,3)";

但是有了这个,显然我总是从现在获取数据 - 1 个月。所以我要向用户展示的数据是错误的,因为它从一个月中的某个地方开始,在另一个月中的某个地方结束。我希望期间从每月的第一天开始,到每月的最后一天结束。

我的第一个想法是,我可以从当前日期中减去当月已经过去的天数,得到上个月的第一天,但​​我不知道该怎么做。我也不知道如何得到那个月的名字。

【问题讨论】:

    标签: php mysql sql date timestamp


    【解决方案1】:

    您可以使用 PHP 函数 mktimestrtotime 根据当前日期计算任意日期。

    因此,与其使用笨拙、不可读的 SQL 函数,我宁愿直接在 PHP 中计算所需的时间段:

    $period_end = mktime(0,0,0, date('n'), 1, date('Y')); // first of current month, time 00:00:00
    $period_begin = strtotime('-3 months', $period_end);
    

    然后您可以将它们嵌入到您的 SQL 查询中,如下所示:

    $query = "SELECT * FROM table WHERE publish_up BETWEEN '" .
             date('Y-m-d H:i:s', $period_begin) ."' AND '" .
             date('Y-m-d H:i:s', $period_end) ."' AND " 
             "created_by = '$editorID' AND state = 1 AND sectionid in (1,2,3)";
    

    【讨论】:

    • 很抱歉回答迟了。首先感谢您的想法!我会试试看。由于我需要几个单一的输出,我将尝试使用一些变量而不是 -3 个月,并在每次运行中增加它。到目前为止谢谢,我会在尝试后回答
    • 我想如果我以某种方式将变量 $period_end 更改为上个月的最后一个月,并将 $period_begin 更改为上个月的第一天,我可以增加一个变量,直到我匹配用户输入和通过我的for循环你解决了我的问题:)
    • 太好了。如果你能接受我的回答,我会很高兴。
    • 当然抱歉昨天忘记了 :) 没有设法得到最后一个月 :( 看来我需要练习一下 mktime 函数
    • 查看日期函数的文档中的格式字符't'。它给出了给定月份的天数。所以当月的最后一天是:mktime(0,0,0, date('n'), date('t'), date('Y'))
    【解决方案2】:

    使用 EXTRACT YEAR_MONTH 可以轻松查看日期是否在所需的月份内。

    "SELECT MONTHNAME(publish_up) as month, SUM(some_column), ... 
     FROM mytable 
     WHERE extract(year_month from publish_up) BETWEEN
           extract(year_month from (now() - INTERVAL ".$history." MONTH)) AND
           extract(year_month from now())
     AND created_by = '".$editorID."' AND state = 1 AND sectionid in (1,2,3)
     GROUP BY MONTHNAME(publish_up)";
    

    【讨论】:

    • 抱歉,回答迟了。我尝试了您的代码,但我的数据库中总是出现语法错误。我想可能是因为from (now() - INTERVAL 没有桌子?但是到目前为止感谢您的回答
    • 当 $history 为 1 时,"now() - INTERVAL ".$history." MONTH" 应该转换为 now() - INTERVAL 1 MONTH。你到底得到了什么错误?与 $history 和 $editorID 连接后,您的 SQL 字符串实际上是什么样的?
    • 我直接在我的SQL数据库中尝试了代码,前面没有php。 SELECT MONTHNAME(publish_up) as month, sum(id, publish_up) FROM jos_content WHERE extract(year_month from publish_up) BETWEEN extract(year_month from (now() - INTERVAL 1 MONTH)) AND extract(year_month from now()) AND created_by = 254268 AND state = 1 AND sectionid in (1,2,3) GROUP BY MONTHNAME(publish_up) 我会在第 1 行得到 #1064 语法错误
    • 错误可能是sum(id, publish_up)。这是什么意思? SUM 采用一个参数,即使您调用了 SUM(id) 或 SUM(publish_up);为什么要总结 id 或日期?这是没有意义的。要查找错误,顺便说一句,换行更容易。只要所有内容都在一行中,并且您在第 1 行中遇到语法错误,那就没什么好说的了。做这 10 行左右,在第 3 行得到一个语法错误,你就会知道更多。
    【解决方案3】:
    SELECT * 
    FROM   table 
    WHERE  create_by = '$editorID' AND 
           state = 1 AND 
           sectionid in (1,2,3) AND
           published_up > DATE_FORMAT(NOW() ,'%Y-%m-01') - INTERVAL ".$history." MONTH
    

    【讨论】:

    • 这将包括当月的所有记录,这是 OP 不想要的。
    【解决方案4】:

    这将为您提供上个月的月底:

    DATE_SUB(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 1 DAY)
    

    月份名称见here

    【讨论】:

    • 感谢您的回答,对于迟到的反应深表歉意。为了完成您的代码并将其用于多种用途,我将其更改为 SELECT DATE_SUB(DATE_FORMAT(NOW() - INTERVAL ".$month." MONTH, '%Y-%m-01'), INTERVAL 1 DAY) 现在我只需要在上个月的第一天使用相同的代码,并且我得到了我的“介于”。到目前为止谢谢!
    • SELECT DATE_FORMAT(NOW() - INTERVAL ".$month."+1 MONTH, '%Y-%m-01') 怎么样?
    猜你喜欢
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多