SQL - 按超过某个值的新近度排序

问题描述 投票:0回答:4

我有一张

job
桌子,还有一张
jobstatus
桌子:

Job ( 
    id SERIAL PRIMARY KEY NOT NULL, 
    PackageInstance_id bigint NOT NULL, 
    BuildClient_id bigint 
) 

JobStatus ( 
    id SERIAL PRIMARY KEY NOT NULL, 
    Job_id bigint NOT NULL, 
    Status_id bigint NOT NULL, 
    time timestamp NOT NULL DEFAULT now() 
)

我想选择所有最近报告状态为“完成”的作业,并且该状态的时间戳表示作业在最后 10 分钟内完成。

我已经可以得到未完成的工作,是时间让我得到了。我假设我们需要做一些

DATEDIFF
SELECT
时间戳比
now()
不到 x 分钟或任何函数来获得
CURRENT_TIMESTAMP
.

sql database postgresql timestamp greatest-n-per-group
4个回答
2
投票
select j.*
from
    job j
    inner join (
        select j.id, max("time") "time"
        from
            job j
            inner join jobstatus js on j.id = js.job_id
        where
            "time" > now() - interval '10 minutes'
            and
            js.status_id = 3 -- finished
        group by j.id
    ) s on s.id = j.id

0
投票

我看到你有 status_id 所以应该还有一张包含 job_status_names 的表

select * 
from jobs j 
 join ( select 
         job_id, 
         status_id 
       from jobstatus 
       where (job_id, time) in ( select job_id, 
                                        max(time) 
                                 from jobstatus 
                                 where time >= now() - interval '10 minutes'
                                 group by job_id) 
      ) as foo on j.id = foo.job_id 
 where status_id = (select id from job_status_names where status_name = 'finished')

0
投票

这里是你如何做到这一点:

select
    js.JobId
    , MAX(js.StatusDate) as LatestStatusDate
into #MostRecentStatuses
from #JobStatus js
group by js.JobId

select *
from #MostRecentStatuses mrs
join #JobStatus js
    on js.JobId = mrs.JobId
    and js.StatusDate = mrs.LatestStatusDate
join #JobStatusNames jsn
    on jsn.JobStatusId = js.JobStatusId
join #Jobs j
    on j.Id = mrs.JobId
where
    mrs.LatestStatusDate >= DATEADD(MINUTE, -10, GETDATE())
    and jsn.StatusName = 'Finished'

我假设你的表是这样定义的:

create table #Jobs
(
    Id int
    , Name nvarchar(max)
)

create table #JobStatusNames
(
    JobStatusId int
    , StatusName nvarchar(max)
)

create table #JobStatus
(
    JobId int
    , JobStatusId nvarchar(max)
    , StatusDate datetime
)

0
投票

SELECT
LATERAL
子查询中每个作业的最新状态行,并将您的过滤器放在连接子句中:

SELECT *
FROM   job j
JOIN   LATERAL (
   SELECT status_id, time
   FROM   jobstatus js
   WHERE  js.job_id = j.id            -- lateral reference
   ORDER  BY js.time DESC NULLS LAST  -- add tiebreaker if tie is possible
   LIMIT  1
    ) js ON js.status_id = 3  -- whatever signifies 'finished'
        AND js.time >= LOCALTIMESTAMP - interval '10 min';

参见:

ORDER BY
子句有效,因为
false
true
null
之前排序。所以“完成”是第一位的(如果它存在)。外面的
SELECT
只拿成品的

让你的

status_id
类型
boolean
或者可能
enum
如果你有超过“完成”/“未完成”。
bigint
没有意义。

所有其他

bigint
专栏可能是
integer
.

© www.soinside.com 2019 - 2024. All rights reserved.