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

时间:2012-11-20 09:41:11

标签: sql database postgresql timestamp

我有一个“工作”表和一个“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() 
)

如果此状态的时间戳指示相关的jon在过去10分钟内完成,我想查询选择最近报告状态为“已完成”的所有作业。

我不是SQL向导。怎么设计这个? - 我已经可以获得未完成的工作,这是我获得的时间。我假设我们需要做一些DATEDIFF,以及SELECT,其中时间戳距离Now()小于x分钟,或者无论函数是什么来获得CURRENT_TIMESTAMP。

有任何帮助吗?我正在使用PostgreSQL。

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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
)

答案 2 :(得分: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')

答案 3 :(得分:0)

可以解决like this related task(点击链接获取更多解释):

SELECT * FROM (
    SELECT DISTINCT ON (j.id)
           j.*
    FROM   job j
    JOIN   jobstatus js ON js.job_id = j.id
    WHERE  job_time >= (now() - interval '10 min')
    ORDER  BY j.id, js.status_id <> 123  -- or whatever signifies 'finished'
    ) x
WHERE status_id = 123 -- 'finished'
  • ORDER BY子句有效,因为FALSETRUENULL之前排序。所以'完成'首先出现(如果它存在)。外SELECT只接受完成的。

  • 为什么status_id成为bigint?如果您有超过'已完成'/'未完成',请将其更改为boolean或可能enumbigint毫无意义。

  • 您的所有其他bigint列可能应为integer