SELECT n行,日期前存在n-1行

时间:2018-06-19 18:53:11

标签: mysql select mysqli

我正在尝试创建一个MySQL查询,该查询将选择最新的4行(按date DESC,Ymd格式排序),其中最新的datedate_x之后,至少date_x+1之前存在3行。例如,考虑以下记录:

-----------------------
|  id  |     date     | 
|   1  |  2018-01-01  |
|   6  |  2018-01-02  |
|  10  |  2018-01-03  |
|  26  |  2018-01-04  |
|  27  |  2018-01-05  |
|  34  |  2018-01-06  |
|  60  |  2018-01-07  |
-----------------------

如果date_x ='0000-00-00',则应返回:

-----------------------
|  id  |     date     | 
|   1  |  2018-01-01  |
|   6  |  2018-01-02  |
|  10  |  2018-01-03  |
|  26  |  2018-01-04  |
-----------------------

如果date_x ='2018-01-04',则应返回:

-----------------------
|  id  |     date     | 
|  27  |  2018-01-02  |
|  34  |  2018-01-03  |
|  60  |  2018-01-04  |
|  27  |  2018-01-05  |
-----------------------

如果date_x ='2018-01-07',则应返回:

-----------------------
|  id  |     date     |
-----------------------

有什么方法可以通过一个查询有效地做到这一点吗?

2 个答案:

答案 0 :(得分:1)

演示为'2018-01-04'提供了值date_x

获取“ date_x + 1”之前的行数。 (我们可以将其与文字值进行比较,以确定是否至少有3行。)

 SELECT COUNT(1) AS cnt
   FROM mytable d
  WHERE d.date <  '2018-01-04'  + INTERVAL 1 DAY

获取date之后具有date_x值的行数。 (我们可以将其与文字进行比较,以确定在date之后是否存在[{至少一个]行,其行号为date_x。)

 SELECT COUNT(1) AS cnt
   FROM mytable c
  WHERE c.date >  '2018-01-04'  + INTERVAL 0 DAY

获取(最多)四个最新行...

 SELECT t.id
      , t.date
   FROM mytable t
  ORDER BY t.date DESC
  LIMIT 4

总而言之,我们可以做这样的事情

 SELECT t.id
      , t.date
   FROM mytable t
  WHERE 2 < ( SELECT COUNT(1) AS cnt
                FROM mytable d
               WHERE d.date <  '2018-01-04'  + INTERVAL 1 DAY
            )
    AND 0 < ( SELECT COUNT(1) AS cnt
                FROM mytable c
               WHERE c.date >  '2018-01-04'  + INTERVAL 0 DAY
            )
  ORDER BY t.date DESC
  LIMIT 4

其他查询模式可以达到相同的结果,例如:

 SELECT t.id
      , t.date
   FROM mytable t
   JOIN ( SELECT COUNT(1) AS cnt
            FROM mytable d
           WHERE d.date <  '2018-01-04'  + INTERVAL 1 DAY
        ) q
     ON q.cnt > 2
   JOIN ( SELECT COUNT(1) AS cnt
            FROM mytable c
           WHERE c.date >  '2018-01-04'  + INTERVAL 0 DAY
        ) r
     ON r.cnt > 0
  ORDER BY t.date DESC
  LIMIT 4

查询以降序返回行。如果我们想对这些行进行重新排序,可以将整个查询包装在括号中,并将其作为内联视图引用

SELECT z.id
     , z.date
  FROM (
          -- query goes here
       ) z
 ORDER BY z.date ASC

规范尚不完全清楚...如果少于四行怎么办?如果日期> date_x + 1多于一行怎么办?

我怀疑规范中还有更多我没有发现的问题。 Spec说我们希望“最新日期”是在 date_x之后,...尚不清楚我们是否只返回date_x之后的 first 日期。 ,而忽略以后的日期。

答案 1 :(得分:0)

我认为这是您要执行的操作的要旨:

select t.*
from t
where date >= @date and
      (select count(*) from t t2 where t2.date >= @date) >= 3
order by date
limit 4;

您的问题和样本数据非常混乱。您说的是date desc排序,但样本结果似乎首先具有最小的日期。您提到了x_date + 1,但这并不是结果中的任何地方。我认为以上内容即可满足您的要求。