根据时间戳组织数据 mysql + PHP

Organize Data based on Timestamp mysql + PHP

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

我写过这段代码:

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();
}

我正在尝试找出一种方法来拆分事物,例如,"Today"、"Yesterday"、"Day before Yesterday" 等等,只要被认为是正常的,例如也许整整一个月。

*我如何使用 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
        )

很明显:我想打印带有今天时间戳的所有内容。接下来,所有带有 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)

如何获取所有行并检查 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 ... 等,并根据需要显示它们。

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

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

第三,你可以使用union。您根据不同的场景创建 3 个单独的查询 select,然后使用 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 语句 return 在同一列中,否则会出错。您可能还想阅读 UNION ALL。 UNION 和 UNION ALL 之间有一些细微差别,但差别不大。

下面是我将如何处理此问题的示例。我不会更改您的查询 - 没问题。假设您想要显示数据库中的所有内容,从最新到最早排序 post。让 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
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

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

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

您应该更改 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!";
}