MySql查询如何获取日期计数小于的第一个

bpzcxfmw  于 2023-03-11  发布在  Mysql
关注(0)|答案(1)|浏览(165)

目标

因此,我的目标是有一个SQL查询返回第一个日期,其中不超过5个记录遵守where子句(userId)。

当前架构

|id|user_id|scheduled_at|
|1 |1      |2023-03-16  |
|2 |1      |2023-03-15  |
|3 |3      |2023-03-15  |
|4 |1      |2023-03-15  |
|5 |1      |2023-03-15  |

∮我有什么成就∮

count(*) as cnt,
    scheduled_at
    from estudojo.user_scheduled_questions as uq where uq.user_id='1' and scheduled_at >=  '2023-03-14'
    group by scheduled_at
    having cnt < 5
    order by cnt ASC limit 1

回报是:

┌─────────┬─────┬─────────────────────────────┐
│ (index) │ cnt │        scheduled_at         │
├─────────┼─────┼─────────────────────────────┤
│    0    │  3  │ '2023-03-15'                │
└─────────┴─────┴─────────────────────────────┘

但仍然不是我想要的,因为第一个可用的日期是2023-03-14

期待

我以为会是这样:

┌─────────┬─────┬─────────────────────────────┐
│ (index) │ cnt │        scheduled_at         │
├─────────┼─────┼─────────────────────────────┤
│    0    │  0  │ '2023-03-14'                │
└─────────┴─────┴─────────────────────────────┘
qyyhg6bp

qyyhg6bp1#

您的数据中现在有该用户在3月14日的行,因此查询无法返回您期望的结果。
如果你想让查询检查一个固定的日期范围,那么你需要先生成一个范围,然后用一个left join来调用这个表。在MySQL 8.0中,我们可以用递归查询来完成这个任务:

with recursive all_dates as (
    select '2023-03-14' scheduled_at
    union all 
    select scheduled_at + interval 1 day from all_dates where scheduled_at < current_date
)
select ad.scheduled_at, count(uq.user_id) cnt
from all_dates as ad
left join estudojo.user_scheduled_questions as uq
    on uq.user_id = 1 and uq.scheduled_at = ad.scheduled_at
group by ad.scheduled_at
having count(uq.user_id) < 5

递归CTE生成3月14日到今天之间的所有日期(您可能需要调整边界);然后,外部查询计算每个日期(以及给定用户)在源表中可以找到多少行,剩下的只是使用having(您在原始查询中已经有了)进行聚合和过滤。
注意:如果表中的日期包含时间部分,我们需要将连接条件更改为不等式:

...
left join estudojo.user_scheduled_questions as uq
    on uq.user_id = 1 
    and uq.scheduled_at >= ad.scheduled_at
    and uq.scheduled_at <  ad.scheduled_at + interval 1 day

相关问题