在SQL中查找比当前记录旧/新的记录

时间:2020-04-15 17:45:08

标签: php mysql

我正在尝试编写一条SQL语句,该记录为我提供上一条/下一条记录。

“我的帖子”表中的记录既可以是博客帖子,也可以是发运日志(基于posts_isLog列为1或0)。

我正在使用以下准备好的语句根据日期返回当前的运输日志。列post_createdOn是日期/时间数据类型。我正在使用一个like语句来将我的通过日期与查询进行匹配,因为这是通过URL找到的,即“ shipslog / 2020年4月14日”。日期已更改,以匹配数据,因此yyyy-mm-dd,因此没有问题。

//query
$this->db->query('SELECT * 
                  from posts 
                    INNER JOIN voyages ON posts.post_voyage = voyages.voyage_id 
                  WHERE post_createdOn LIKE :date 
                  AND post_isLog = 1 
                  AND post_live = 1');
//bind values
$this->db->bind(':date', '%'.$date.'%');
//get the results
$row = $this->db->single();
return $row;

我无法计算出SQL以根据当前记录查找下一个/上一个发运日志。

我认为我要写的是...“从post_createdOn小于当前记录的post_createdOn日期的帖子中选择所有帖子”。

我正在尝试

//query
$this->db->query('SELECT * 
                  from posts 
                  WHERE post_createdOn < :date 
                    AND post_isLog = 1 
                    AND post_live = 1');
//bind values
$this->db->bind(':date', '%'.$date.'%');
//get the results
$row = $this->db->single();
return $row;

但是我知道这不是指当前记录。完全陷入困境!

这是指$this->db->single();

//get single record as an object
    public function single() {
      $this->execute();
      return $this->statement->fetch(PDO::FETCH_OBJ);
    }

2 个答案:

答案 0 :(得分:1)

感谢所有答案!

在@RiggsFolly的帮助下,我似乎快到了。我取出了%,查询返回了结果。我只需要返回第一行就需要对结果进行排序!

public function getPreviousLog($date) {
    //query
    $this->db->query('SELECT * 
                      from posts 
                      WHERE post_createdOn < :date 
                      AND post_isLog = 1 
                      AND post_live = 1 
                      ORDER BY post_createdOn DESC');
    //bind values
    $this->db->bind(':date', $date);
    //get the results
    $row = $this->db->single();
  }

答案 1 :(得分:0)

您可以使用LAG和LEAD进行此操作,但是如果您有很多列,这会有些乏味。而是尝试:

WITH cte AS(
    SELECT *, ROW_NUMBER() OVER(ORDER BY post_CreatedOn) rn
    FROM posts 
    WHERE 
      post_createdOn < :date AND 
      post_isLog = 1 AND 
      post_live = 1
)

SELECT * 
FROM
  cte curr
  LEFT JOIN cte next ON curr.rn+1 = next.rn
  LEFT JOIN cte prev ON curr.rn-1 = prev.rn

您似乎没有指定任何分区-您只是说表是一长串带日期的记录,每个记录都有一个上一个和一个根据日期的下一个。如果有某种观点认为列组是一起组成的,则将将它们分组的行作为PARTITION BY放入行号中,并将其添加到prev curr和next

之间的join ON子句中。

对于“下一个”行是否超出日期限制,我尚不清楚。例如,如果您有两行2000-12-31和2001-01-01,并且将date参数设置为2001-01-01,则后面的记录将被排除为“当前”,但这意味着2000-12-第31行的“ next”应该为null,或者为2001-01-01行

如果可以(该查询不会返回它),则将该谓词从CTE中取出,并将其放在curr.post_createdOn中的主查询WHERE中


如果您要建立某种分页系统,每天要创建一个日志,并且需要3行,请考虑:

WITH cte AS(
    SELECT *
    FROM posts 
    WHERE 
      post_isLog = 1 AND 
      post_live = 1
)

SELECT. * 
FROM cte
WHERE post_createdOn IN(
  SELECT MAX(post_createdOn) FROM cte WHERE post_createdOn < @date
  UNION ALL
  SELECT @date
  SELECT MIN(post_createdOn) FROM cte WHERE post_createdOn > @date
)
相关问题