根据Timestamp mysql + PHP组织数据

时间:2015-04-09 13:20:31

标签: php mysql pdo

我正在尝试以下列方式组织DATA的输出: 今天,昨天和昨天之前的所有内容都有相应的完整日期时间减去当然的时钟时间。为了更好地理解,请查看下面的屏幕截图:

enter image description here

我写了这段代码:

try{
    $db = new PDO("mysql:host=" .$hostname. ";dbname=" .$database. "", "" .$user. "", "" .$pass. "");
  $db->setAttribute(PDO::ATTR_PERSISTENT, true);
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $notifications = $db->prepare("SELECT * FROM reports
    ORDER BY timestamp DESC");
  $notifications->execute();

  $result = (object)$notifications->fetchAll(PDO::FETCH_OBJ);

  echo "<pre>";

  print_r($result);

    echo "</pre>";

}
catch(PDOException $e)
{
    echo $e->getMessage();
}

我正试图找出一种分解方法,例如,&#34;今天&#34;,&#34;昨天&#34;,&#34;昨天前一天&#34;等等,只要认为是正常的,例如也许整整一个月。

*如何使用PDO预处理语句正确构建此代码? *

   [Today] => stdClass Object
        (
            [id] => 1
            [timestamp] => 2015-04-09 13:20:05
            [seen] => 0
        )
    [Yesterday] => stdClass Object
        (
            [id] => 2
            [timestamp] => 2015-04-08 15:30:50
            [seen] => 0
        )

显然:我想用TODAY的时间戳打印所有内容。接下来,使用YESTERDAYS时间戳的所有内容。等等。

SQL:

// Today
AND DATE(from_unixtime(comment_date)) = CURRENT_DATE

// Yesterday
AND DATE(from_unixtime(comment_date)) =  DATE_SUB(CURRENT_DATE,INTERVAL 1 DAY)

// This week
AND YEARWEEK(from_unixtime(comment_date), 1) =  YEARWEEK(CURRENT_DATE, 1)

// This month
AND YEAR(from_unixtime(comment_date)) = YEAR(CURRENT_DATE)
AND MONTH(from_unixtime(comment_date)) = MONTH(CURRENT_DATE)

5 个答案:

答案 0 :(得分:3)

以下是我将如何处理此问题的示例。我不会改变你的查询 - 它很好。假设您要显示从最新到最早的帖子中排序的数据库中的所有内容。让PHP处理繁重的工作。我故意将一些东西分成多行而不是嵌套函数以使其更容易阅读。如你认为的那样冷凝。

我并不是说这是最好的方法。只有我用的东西。

//MOCK UP SOME DISPLAY DATA - YOU WOULD USE YOUR QUERY RESULT INSTEAD
$rows = array();
$rows[] = date('Y-m-d H:i:s');
$rows[] = date('Y-m-d H:i:s');
$rows[] = date('Y-m-d H:i:s');
$rows[] = date('Y-m-d H:i:s', mktime(0, 0, 0, date('n'), date('j') - 1, date('Y')));
$rows[] = date('Y-m-d H:i:s', mktime(0, 0, 0, 12, 24, 2014));
$rows[] = date('Y-m-d H:i:s', mktime(0, 0, 0, 12, 25, 2014));
$rows[] = date('Y-m-d H:i:s', mktime(0, 0, 0, 12, 26, 2014));
$rows[] = date('Y-m-d H:i:s', mktime(0, 0, 0, 3, 2, 2001));

//CREATE AN ARRAY OF THE REPLACEMENTS YOU WANT
$aArray = array();
$aArray[date('Y-m-d')] = 'Today';
$aArray[date('Y-m-d', mktime(0, 0, 0, date('n'), date('j') - 1, date('Y')))] = 'Yesterday';
$aArray[date('Y-m-d', mktime(0, 0, 0, date('n'), date('j') - 2, date('Y')))] = 'Day before Yesterday';
$aArray['2014-12-25'] = 'Christmas 2014';

//INITIALIZE SOME VARIABLES
$cLastHeader = '';
$cCurrHeader = '';

//THIS WOULD BE YOUR QUERY RESULTS LOOP
foreach ($rows AS $nNull => $cDate) {
    $cLookup = substr($cDate, 0, 10);  //TRIM OUT THE TIME FROM CURRENT RECORD

    //IS DATE IN ARRAY? IF NOT, FORMAT
    if (isset($aArray[$cLookup])) {
        $cCurrHeader = $aArray[$cLookup];
    } else {
        $cCurrHeader = $cLookup; //WOULD SHOW 'YYYY-MM-DD'
        $cCurrHeader = date('F Y', strtotime($cLookup)); //WOULD SHOW 'MONTH YYYY'
    }

    //HAS HEADER CHANGED? IF SO PRINT
    if ($cCurrHeader != $cLastHeader) {
        $cLastHeader = $cCurrHeader;
        print($cCurrHeader . "\n");
    }

    //PRINT RECORD
    print("\t" . $cDate . "\n");
}

这个输出是:

Today
    2015-05-28 18:40:35
    2015-05-28 18:40:35
    2015-05-28 18:40:35
Yesterday
    2015-05-27 00:00:00
December 2014
    2014-12-24 00:00:00
Christmas 2014
    2014-12-25 00:00:00
December 2014
    2014-12-26 00:00:00
March 2001
    2001-03-02 00:00:00

答案 1 :(得分:3)

SELECT IF( DATEDIFF( NOW( ) , `timestamp` ) =0, "Today", if( DATEDIFF( NOW( ) , `timestamp` ) =1, "Yesterday", DATE_FORMAT( `timestamp`, '%M %d' ) ) ) AS day,
id,timestamp,seen
FROM reports
ORDER BY timestamp DESC

尝试通过查询解决您的问题,检查它是否对您有帮助。

根据给定的屏幕截图,在今天和昨天之后,此查询将为您提供月份和日期。

答案 2 :(得分:1)

如何获取所有行并在PHP中检查日期然后将存在于同一时间范围内的结果分组到单独的数组中,如下所示:

$notifications = $db->prepare("SELECT * FROM reports
ORDER BY timestamp DESC");
$notifications->execute();
$rows = $notifications->fetchAll(PDO::FETCH_ASSOC);
foreach($rows as $row ){
 if ( date('Ymd') == date('Ymd', strtotime($row['timestamp'])) ){
     $today_rows[] = $row;
    }
else if (date('Ymd', strtotime('yesterday')) == date('Ymd', strtotime($row['timestamp'])) ){
 $yesterday_rows[] = $row;
 }
else if () ... etc 
}

现在,您可以在视图中使用$ today_row,$ yesterday_rows ...等,并根据需要显示它们。

答案 3 :(得分:1)

有多种方法可以解决这个问题。 首先,您可以创建单独的调用并合并php端的数据。

其次,您可以使用子查询,但我不建议使用子查询,因为它们有点棘手并且可能占用大量资源。

第三,你可以使用工会。您可以根据不同的方案创建3个单独的查询,然后使用union。这样,您将在一次通话中获得所有结果。

SELECT *, 'today' as day FROM table WHERE DATE(from_unixtime(comment_date)) = CURRENT_DATE
UNION
SELECT *, 'yesterday' as day FROM table WHERE MONTH(from_unix_MONTH(CURRENT_DATE)) = MONTH(CURRENT_DATE)

基本上,联合是将不同的select语句组合成一个查询。您可以根据需要合并任意数量的select语句。但是,请注意,您希望所有select语句都返回相同的列,否则会出错。你也许想读一下UNION ALL。 UNION和UNION ALL之间存在一些细微差别,但不是很明显。

答案 4 :(得分:1)

您应该更改MySQL查询以获取日期差异。

SELECT *,DATEDIFF(NOW(),`timestamp`) as `dateDifference` FROM `reports` ORDER BY `dateDifference`

此处提供了一个示例http://sqlfiddle.com/#!9/ecad0/6

然后在dateDifference上运行if语句或switch-case以按您希望的方式组织结果。 下面给出了合适的switch-case语句的例子

switch (true) {
    case ($dateDifference===0):
        echo "Today's reports!";
        break;
    case ($dateDifference===1):
        echo "Yesterday's reports!";
        break;
    case ($dateDifference>1):
        echo "Even older reports!";
        break;
    case ($dateDifference<0):
        echo "An unexpected error occurred. Please contact your system administrator!";
}