我正在尝试创建一个MySQL查询,该查询将选择最新的4行(按date
DESC,Ymd格式排序),其中最新的date
在date_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 |
-----------------------
有什么方法可以通过一个查询有效地做到这一点吗?
答案 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
,但这并不是结果中的任何地方。我认为以上内容即可满足您的要求。