在SQL中查找最先发生的事件 问题
在我们的应用程序中,我们存储房间清洁时的重复事件。任务事件被分配给一个用户并被赋予一个类别。我们使用SQL视图“清理任务”来获取特定日期的所有计划任务。视图将返回如下内容 从清洁任务中选择*,其中计划日期=当前日期; >房间id、用户id、类别、预定地点 > 1, 1, 3, 2020-06-04 现在的问题是,我们希望按照房间id、用户id和类别对第一个即将到来的活动进行分组 例如,假设我们有三间1类的房间,每天都要打扫,两间2类的房间每周五打扫。如果今天是星期三,那么我希望查询返回三个category 1事件和两个category 2事件,这两个事件计划在星期五发生,这些行用*标记。如果是星期五,那么查询将返回计划在星期五的所有五个事件在SQL中查找最先发生的事件 问题,sql,date,select,mariadb,greatest-n-per-group,Sql,Date,Select,Mariadb,Greatest N Per Group,在我们的应用程序中,我们存储房间清洁时的重复事件。任务事件被分配给一个用户并被赋予一个类别。我们使用SQL视图“清理任务”来获取特定日期的所有计划任务。视图将返回如下内容 从清洁任务中选择*,其中计划日期=当前日期; >房间id、用户id、类别、预定地点 > 1, 1, 3, 2020-06-04 现在的问题是,我们希望按照房间id、用户id和类别对第一个即将到来的活动进行分组 例如,假设我们有三间1类的房间,每天都要打扫,两间2类的房间每周五打扫。如果
room_id, user_id, category, scheduled_at
----------------------------------------
10, 1, 1, 2020-06-03 * # Wednesday
20, 2, 1, 2020-06-03 *
30, 3, 1, 2020-06-03 *
10, 1, 1, 2020-06-04 # Thursday
20, 2, 1, 2020-06-04
30, 3, 1, 2020-06-04
10, 1, 1, 2020-06-05 # Friday
20, 2, 1, 2020-06-05
30, 3, 1, 2020-06-05
40, 4, 2, 2020-06-05 *
50, 5, 2, 2020-06-05 *
我的尝试
我尝试了下面的查询,得到了正确的结果,但由于GROUP BY,我不确定结果是否总是正确的。SQL视图正在检索的事件是按顺序创建的
选择房间id、用户id、类别、预定地点
来自房间清洁任务
其中计划时间>=当前日期
按房间id、用户id、类别分组
我第一次尝试使用MIN,但发现结果不正确。可能是由于分组原因
选择房间id、用户id、类别、预定时间、预定时间
从清洁任务
其中计划时间>=当前日期
按房间id、用户id、类别分组
我还尝试在子查询中使用MIN,但没有成功。我敢肯定,由于子查询中的MIN,内部连接失败
选择t.room\u id、t.user\u id、t.category、t.scheduled\u at
从…起
选择房间id、用户id、类别、预定的分钟数
从清洁任务
按房间id、用户id、类别分组
即将到来的
内部联接清理任务
在t.room\u id=comming.room\u id上
t.user\u id=comming.user\u id
和t.category=uncoming.category
和t.category>=当前日期
一个通常有效的选项是使用子查询进行筛选:
select ct.*
from cleaning_tasks ct
where ct.scheduled_at = (
select min(ct1.scheduled_at)
from cleaning_tasks ct1
where ct1.room_id = ct.room_id and ct1.scheduled_at >= current_date
)
性能,考虑ROMSOIDID,StReDePo.A./P>< P>一个通常有效的选项是用子查询过滤:
select ct.*
from cleaning_tasks ct
where ct.scheduled_at = (
select min(ct1.scheduled_at)
from cleaning_tasks ct1
where ct1.room_id = ct.room_id and ct1.scheduled_at >= current_date
)
关于性能,考虑ROMSOID,SealDeTo.A./P>< P>上的索引。如果我正确地理解了,您希望在今天或之后按房间、用户和类别分组的第一个日程安排。 我会在分区上使用一个ROWNUMBER,并将其放入子查询中,这样您就可以进行筛选
例如:SELECT SUB.*
FROM (
SELECT ROOM_ID
, USER_ID
, CATEGORY
, SCHEDULED_AT
, ROW_NUMBER() OVER (PARTITION BY ROOM_ID, USER_ID, CATEGORY
ORDER BY SCHEDULED_AT ASC) AS ITEM_NUMBER
FROM CLEANING_TASKS
WHERE SCHEDULED_AT >= CURRENT_DATE
) SUB
WHERE ITEM_NUMBER = 1
如果我理解正确的话,您希望在今天当天或之后按房间、用户和类别分组第一个计划的_ 我会在分区上使用一个ROWNUMBER,并将其放入子查询中,这样您就可以进行筛选 例如:
SELECT SUB.*
FROM (
SELECT ROOM_ID
, USER_ID
, CATEGORY
, SCHEDULED_AT
, ROW_NUMBER() OVER (PARTITION BY ROOM_ID, USER_ID, CATEGORY
ORDER BY SCHEDULED_AT ASC) AS ITEM_NUMBER
FROM CLEANING_TASKS
WHERE SCHEDULED_AT >= CURRENT_DATE
) SUB
WHERE ITEM_NUMBER = 1
遗憾的是,这个问题对我不起作用。我还添加了ct1.user\u id=ct.user\u id和ct1.category=ct.category。它只找到了为当前\u日期安排的事件。@Gradox:。正如你的问题中所描述的那样,它似乎运行良好,产生了我在房间id 10上筛选的预期结果。也许我的问题措辞不好,但这些结果不是我想要的。在示例中,每个用户id每个类别每个预定时间,房间10只应出现一次。在你的小提琴室里,10出现了三次。在这种情况下,我应该只在=2020-06-03的预定时间出现一次,因为它是结束或等于当前时间的事件。再说一次,如果我不清楚,我很抱歉。@Gradox:啊,好吧,那就更简单了!我修改了答案并添加了性能建议。我仍然需要比较用户id和类别id以获得所需的结果,但我99%确定查询返回的正是我想要的结果。您的解决方案看起来比@notmak的简单,因此我将您的答案标记为已接受答案。不过,还是要感谢你们两位的帮助!遗憾的是,这个问题对我不起作用。我还添加了ct1.user\u id=ct.user\u id和ct1.category=ct.category。它只找到了为当前\u日期安排的事件。@Gradox:。正如你的问题中所描述的那样,它似乎运行良好,产生了我在房间id 10上筛选的预期结果。也许我的问题措辞不好,但这些结果不是我想要的。在示例中,每个用户id每个类别每个预定时间,房间10只应出现一次。在你的小提琴室里,10出现了三次。在这种情况下,我应该只在=2020-06-03的预定时间出现一次,因为它是结束或等于当前时间的事件。再说一次,如果我不清楚,我很抱歉。@Gradox:啊,好吧,那就更简单了!我修改了答案并添加了性能建议。我仍然需要比较用户id和类别id以获得所需的结果,但我99%确定查询返回的正是我想要的结果。您的解决方案看起来比@notmak的简单,因此我将您的答案标记为已接受答案。不过,还是要感谢你们两位的帮助!我想这个问题给了我答案
ect行。我明天要做一些测试,但看起来很有希望!虽然这两个查询都可以工作,但考虑到我们在生产中使用的数据集,这个解决方案的速度要快得多。我认为这个查询提供了正确的行。我明天要做一些测试,但看起来很有希望!尽管这两个查询都可以工作,但考虑到我们的数据集正在生产中,这个解决方案的速度要快得多。