我有一个包含大量数据的表,我需要只用一个查询来获取一些信息。
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
答案 0 :(得分:1)
使用MAX( ... ) KEEP ( DENSE_RANK FIRST ORDER BY ... )
根据另一列的最大值获取列的最大值:
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))