事件驱动的选择语句

时间:2017-09-22 12:39:47

标签: sql-server

我有一个事件驱动的mssql数据库,它包含以下列。

id    job_id    request    response   status    date_time  
-----------------------------------------------------------
 1      15     <message>    null     pending   22-09-2017 08:00:00
 2      15     null       <message>  created   22-09-2017 08:00:01
 3      15     null         null     finished  22-09-2017 08:00:02
 4      16     <message>    null     pending   22-09-2017 08:00:05
 5      17     <message>    null     pending   22-09-2017 08:00:06
 6      17     null         null     pending   22-09-2017 08:00:06

我需要进行查询以提取所有待处理状态,但只提取该组中的最后一个状态。所以例如我不想要id 3,因为它已经完成了状态。我确实想要4和6,因为那些是最新的。但是对于数字5,我确实想要消息但是因为有一个超时或者其他任何所需的输出而没有保存在最后一个事件中:

id      job_id    request    response   status    date_time  
-----------------------------------------------------------
 4        16     <message>    null     pending   22-09-2017 08:00:05
 6        17     <message>    null     pending   22-09-2017 08:00:06

现在,我想到的查询现在并没有真正发挥作用。

SELECT id, MAX(job_id), job_id
FROM testtable
HAVING status='pending'
GROUP BY id DESC;

我无法解决如何将两条消息混合在一起的问题。任何帮助表示赞赏。谢谢!

3 个答案:

答案 0 :(得分:2)

尝试获取最后一个状态待定的寄存器

DECLARE @table TABLE 
  ( 
     id         INT 
     ,job_id    INT 
     ,request   VARCHAR(10) 
     ,response  VARCHAR(10) 
     ,status    VARCHAR(10) 
     ,date_time DATETIME 
  ) 

INSERT @table (id,job_id,request,response,status,date_time ) Values
  (1, 15, '<message>',  null     ,'pending ','2017-09-22 08:00:00')
 ,(2, 15, null       ,'<message>','created ','2017-09-22 08:00:01')
 ,(3, 15, null       ,  null     ,'finished','2017-09-22 08:00:02')
 ,(4, 16, '<message>',  null     ,'pending ','2017-09-22 08:00:05')
 ,(5, 17, '<message>',  null     ,'pending ','2017-09-22 08:00:06')
 ,(6, 17, null       ,  null     ,'pending ','2017-09-22 08:00:06');


WITH cte 
     AS (SELECT Row_number() 
                  OVER ( 
                    partition BY job_id 
                    ORDER BY id DESC) RowNumber 
                ,* 
         FROM   @table) 
SELECT * 
FROM   cte 
WHERE  rownumber = 1 
       AND status = 'pending' 

结果

RowNumber            id          job_id      request    response   status     date_time
-------------------- ----------- ----------- ---------- ---------- ---------- -----------------------
1                    4           16          <message>  NULL       pending    2017-09-22 08:00:05.000
1                    6           17          NULL       NULL       pending    2017-09-22 08:00:06.000

阅读您的评论,您需要此代码。如果您没有相同的JobId消息,它将很好地工作

 ;WITH cte 
     AS (SELECT Row_number() 
                  OVER ( 
                    partition BY job_id 
                    ORDER BY id DESC) RowNumber 
                ,* 
         FROM   @table) 
SELECT Max(A.id)        Id 
       ,A.job_id 
       ,Max(IsNull(A.request ,''))  request 
       ,Max(IsNull(A.response,'')) response 
       ,Max(A.status)   status 
       ,Max(A.date_time)date_time 
FROM   @table A 
WHERE  EXISTS (SELECT * 
               FROM   cte B 
               WHERE  B.rownumber = 1 
                      AND B.status = 'pending' 
                      AND A.job_id = b.job_id) 
GROUP  BY A.job_id; 

结果

Id          job_id      request    response   status     date_time
----------- ----------- ---------- ---------- ---------- -----------------------
4           16          <message>             pending    2017-09-22 08:00:05.000
6           17          <message>             pending    2017-09-22 08:00:06.000

获取响应和请求的最后状态

;WITH cte 
     AS (SELECT Row_number() 
                  OVER ( 
                    partition BY job_id 
                    ORDER BY id DESC) RowNumber 
                ,* 
         FROM   @table), 
     cte_lstrequest 
     AS (SELECT Row_number() 
                  OVER ( 
                    partition BY job_id 
                    ORDER BY id DESC) RowNumber 
                ,* 
         FROM   @table 
         WHERE  status = 'pending' 
                AND request IS NOT NULL), 
     cte_lstrespponse 
     AS (SELECT Row_number() 
                  OVER ( 
                    partition BY job_id 
                    ORDER BY id DESC) RowNumber 
                ,* 
         FROM   @table 
         WHERE  status = 'pending' 
                AND response IS NOT NULL) 
SELECT A.id 
       ,A.job_id 
       ,B.request 
       ,C.response 
       ,A.status 
       ,Isnull(b.date_time, a.date_time) Id 
FROM   cte A 
       LEFT JOIN cte_lstrequest B 
              ON a.job_id = b.job_id 
                 AND a.rownumber = b.rownumber 
       LEFT JOIN cte_lstrespponse C 
              ON a.job_id = c.job_id 
                 AND a.rownumber = c.rownumber 
WHERE  a.rownumber = 1 
       AND a.status = 'pending'

结果

Id          job_id      request    response   status     Id
----------- ----------- ---------- ---------- ---------- -----------------------
4           16          <message>  NULL       pending    2017-09-22 08:00:05.000
6           17          <message>  NULL       pending    2017-09-22 08:00:06.000

答案 1 :(得分:0)

SELECT MAX(id), job_id FROM testtable 
    WHERE status='pending' GROUP BY job_id DESC;

这将选择包含&#39; pending&#39;的所有作业。状态选择作业已挂起的最新ID&#39;状态。

答案 2 :(得分:0)

使用row_number PARTITION BY JobId ORDER BY date和/或id DESC可以很容易地完成所有行WHERE row_number = 1。

https://docs.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql