使用Have子句对Group By进行Oracle SQL查询

时间:2018-12-10 14:21:40

标签: sql database oracle oracle11g

我在下面的表A中:

HashKey     QueueStatus     CreationDateTime
1             IMM           21-NOV-18 01.56.28.977628000 AM
1             DEF           21-NOV-18 01.58.28.971628000 AM
1             SENT          21-NOV-18 01.59.28.977628000 AM
2             IMM           21-NOV-18 02.56.28.977628000 AM
2             MAN           21-NOV-18 02.57.28.977628000 AM
2             SENT          21-NOV-18 02.58.28.977628000 AM

我在下面还有另一个表B:

HashKey     ReleaseStatus  TrxNo  
1             SENT          XYZ
2             SENT          XYZ
3             null           XYZ

现在,我需要一个查询,该查询为我提供了B表中所有具有ReleaseStatus作为SENT并具有表A中先前队列状态(CreationDateTime是决定因素)的列。

在此示例中,我需要将结果显示为-

HashKey     ReleaseStatus  TrxNo   QueueStatus as PrevoiusQueueStatus
  1           SENT           XYZ       DEF
  2           SENT           XYZ       MAN

我曾尝试对表A进行&group by查询,但无法通过Haveing子句获取前一个查询。

一些试用版(从具有创建日期时间的Hashkey的QueuedRecords组中选择Hashkey,count(creationdatetime)

2 个答案:

答案 0 :(得分:4)

您可以使用lag()分析函数来获取表A中每一行的先前状态,而不是进行分组:

select HashKey,
  QueueStatus,
  lag(QueueStatus) over (partition by HashKey order by CreationDateTime) as PreviousQueueStatus
from tablea

,然后将其用作子查询(CTE或内联视图)并将其联接到表B:

select b.HashKey, b.ReleaseStatus, b.TrxNo, a.PreviousQueueStatus
from tableb b
join (
  select HashKey,
    QueueStatus,
    lag(QueueStatus) over (partition by HashKey order by CreationDateTime) as PreviousQueueStatus
  from tablea
) a
on a.HashKey = b.HashKey
and a.QueueStatus = b.ReleaseStatus
where b.ReleaseStatus = 'SENT';

   HASHKEY RELE TRX PREV
---------- ---- --- ----
         1 SENT XYZ DEF 
         2 SENT XYZ MAN 

要获得该结果,我假设表A中最后2 / SENT行中的时间应该是该HashKey的最后一次时间,例如02:58而不是01:58,因为它应该控制您看到的其他值。

db<>fiddle

答案 1 :(得分:0)

WITH prev as 
(SELECT HASHKEY, QUEUESTATUS, ROW_NUMBER() OVER (PARTITION BY HASHKEY ORDER BY CREATEDATETIME DESC) rn 
FROM tA) 
select tB.*, prev.QUEUESTATUS 
FROM tB JOIN prev ON tB.HASHKEY = prev.HASHKEY
where tB.RELEASESTATUS='SENT' and prev.rn = 2;