获取基于组内另一个的值

时间:2015-08-13 09:42:43

标签: sql oracle group-by

我有一个包含大量数据的表,我需要只用一个查询来获取一些信息。

PROCESSDATA表的内容:

 PROCESSID | FIELDTIME                   | FIELDNAME | FIELDVALUE
-------------------------------------------------------------------------
 125869    | 10/08/15 10:43:47,139000000 | IDREQUEST | 1236968702
 125869    | 10/08/15 10:45:14,168000000 | state     | Corrected
 125869    | 10/08/15 10:43:10,698000000 | state     | Pending
 125869    | 10/08/15 10:45:15,193000000 | MsgReq    | correctly updated

我需要得到这个结果:

125869  IDREQUEST 1236968702 state Corrected MsgReq  correctly updated

所以我做了这样的询问:

SELECT PROCESSID,
       MAX(CASE WHEN FIELDNAME = 'IDREQUEST' THEN FIELDVALUE END) AS IDREQUEST
       MAX(CASE WHEN FIELDNAME = 'state' THEN FIELDVALUE END) AS state,
       MAX(CASE WHEN FIELDNAME = 'MsgReq' THEN FIELDVALUE END) AS MsgReq
FROM PROCESSDATA
WHERE FIELDNAME IN ('IDREQUEST', 'state', 'MsgReq')
GROUP BY PROCESSID, FIELDNAME;

但我不能得到我想要的东西:

125869  IDREQUEST 1236968702 state Pending MsgReq  correctly updated

我需要根据FIELDVALUE获取FIELDNAME的{​​{1}}。在此示例中,FIELDTIME有两个值FIELDNAME = 'state''Pending', 所以我希望得到'Corrected',因为'Corrected' 10/08/15 10:45:14,168000000> 10/08/15 10:43:10,698000000

3 个答案:

答案 0 :(得分:1)

使用MAX( ... ) KEEP ( DENSE_RANK FIRST ORDER BY ... )根据另一列的最大值获取列的最大值:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE PROCESSDATA ( PROCESSID, FIELDTIME, FIELDNAME, FIELDVALUE ) AS
          SELECT 125869,  TO_TIMESTAMP( '10/08/15 10:43:47,139000000', 'DD/MM/YY HH24:MI:SS,FF9' ), 'IDREQUEST', '1236968702' FROM DUAL
UNION ALL SELECT 125869,  TO_TIMESTAMP( '10/08/15 10:45:14,168000000', 'DD/MM/YY HH24:MI:SS,FF9' ), 'state',     'Corrected' FROM DUAL
UNION ALL SELECT 125869,  TO_TIMESTAMP( '10/08/15 10:43:10,698000000', 'DD/MM/YY HH24:MI:SS,FF9' ), 'state',     'Pending' FROM DUAL
UNION ALL SELECT 125869,  TO_TIMESTAMP( '10/08/15 10:45:15,193000000', 'DD/MM/YY HH24:MI:SS,FF9' ), 'MsgReq',    'correctly updated' FROM DUAL
UNION ALL SELECT 125870,  TO_TIMESTAMP( '10/08/15 10:43:47,139000000', 'DD/MM/YY HH24:MI:SS,FF9' ), 'IDREQUEST', '1236968702' FROM DUAL
UNION ALL SELECT 125870,  TO_TIMESTAMP( '10/08/15 10:45:15,193000000', 'DD/MM/YY HH24:MI:SS,FF9' ), 'MsgReq',    'correctly updated' FROM DUAL  

查询1

SELECT PROCESSID,
       MAX( CASE FIELDNAME WHEN 'IDREQUEST' THEN FIELDVALUE END ) KEEP ( DENSE_RANK FIRST ORDER BY CASE FIELDNAME WHEN 'IDREQUEST' THEN FIELDTIME END DESC NULLS LAST ) AS IDREQUEST,
       MAX( CASE FIELDNAME WHEN 'state'     THEN FIELDVALUE END ) KEEP ( DENSE_RANK FIRST ORDER BY CASE FIELDNAME WHEN 'state'     THEN FIELDTIME END DESC NULLS LAST ) AS state,
       MAX( CASE FIELDNAME WHEN 'MsgReq'    THEN FIELDVALUE END ) KEEP ( DENSE_RANK FIRST ORDER BY CASE FIELDNAME WHEN 'MsgReq'    THEN FIELDTIME END DESC NULLS LAST ) AS MsgReq
FROM   PROCESSDATA
GROUP BY PROCESSID

<强> Results

| PROCESSID |  IDREQUEST |     STATE |            MSGREQ |
|-----------|------------|-----------|-------------------|
|    125869 | 1236968702 | Corrected | correctly updated |
|    125870 | 1236968702 |    (null) | correctly updated |

答案 1 :(得分:0)

试试这个

select t1.PROCESSID, t1.FIELDTIME,t1.FIELDNAME,t1.FIELDVALUE,
t1.STATE,t1.IDREQUEST from PROCESSDATA as t1
inner join
(
select PROCESSID, max(FIELDTIME) as FIELDTIME from PROCESSDATA 
where FIELDNAME IN ('IDREQUEST', 'state', 'MsgReq')
group by PROCESSID
) as t2 on t1.PROCESSID=t2.PROCESSID and t1.FIELDTIME=t2.FIELDTIME
where t1.FIELDNAME IN ('IDREQUEST', 'state', 'MsgReq')

答案 2 :(得分:0)

在这里,我为您写了一个非常快速有效的查询,它可以获取最近7天的processdata。并且它还处理如果两个记录具有完全相同的毫秒,它将只抓取1。

SELECT PD.PROCESSID,
    (SELECT MAX(PD1.FIELDVALUE) FROM PROCESSDATA PD1 WHERE PD.PROCESSID = PD1.PROCESSID AND PD1.FIELDNAME = 'IDREQUEST' AND PD1.FIELDTIME = (SELECT MAX(PD2.FIELDTIME) FROM PROCESSDATA PD2 WHERE PD.PROCESSID = PD2.PROCESSID AND PD2.FIELDNAME = 'IDREQUEST')) AS IDREQUEST,
    (SELECT MAX(PD3.FIELDVALUE) FROM PROCESSDATA PD3 WHERE PD.PROCESSID = PD3.PROCESSID AND PD3.FIELDNAME = 'state' AND PD3.FIELDTIME = (SELECT MAX(PD4.FIELDTIME) FROM PROCESSDATA PD4 WHERE PD.PROCESSID = PD4.PROCESSID AND PD4.FIELDNAME = 'state')) AS state,
    (SELECT MAX(PD5.FIELDVALUE) FROM PROCESSDATA PD5 WHERE PD.PROCESSID = PD5.PROCESSID AND PD5.FIELDNAME = 'MsgReq' AND PD5.FIELDTIME = (SELECT MAX(PD6.FIELDTIME) FROM PROCESSDATA PD6 WHERE PD.PROCESSID = PD6.PROCESSID AND PD6.FIELDNAME = 'MsgReq')) AS MsgReq
FROM PROCESSDATA PD
WHERE PD.PROCESSID IN
      (SELECT PD7.PROCESSID FROM PROCESSDATA PD7 WHERE PD7.FIELDTIME >= (GETDATE()-7))