根据时间戳组织数据 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!";
}
我正在尝试按以下方式组织 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!";
}