2017-02-13 79 views
0

有人建議我改進此子查詢,以便能夠根據以下計算獲取單個記錄,本帖子下面的子查詢會帶來以下結果:如果在同一天可以找到多個記錄,請選擇一個值

PERCENT ¦ LOG_DATE ¦ APP ¦ REQ_ID 
55 ¦ 2017-02-07 15:44:22 ¦ HUO ¦ 253333 
63 ¦ 2017-02-08 10:42:18 ¦ CQS ¦ 265265 
75 ¦ 2017-02-08 06:55:12 ¦ CQS ¦ 265265 
84 ¦ 2017-02-09 08:35:42 ¦ CQS ¦ 265265 
40 ¦ 2017-02-09 09:45:14 ¦ PLK ¦ 277777 

我想看到的只是結果,它具有每日期的最新日期(al.AU_TIME)內的記錄。我們的目標是努力尋找具有'63'百分比值的記錄。查詢應該帶來:

55 ¦ 2017-02-07 15:44:22 ¦ HUO ¦ 253333 
63 ¦ 2017-02-08 10:42:18 ¦ CQS ¦ 265265 
84 ¦ 2017-02-09 08:35:42 ¦ CQS ¦ 265265 
40 ¦ 2017-02-09 09:45:14 ¦ PLK ¦ 277777 

那麼我應該怎麼做,如果多個記錄在同一天有相同的REQ_ID。

SELECT TO_NUMBER(RTRIM(ap.AP_NEW_VALUE,'%')) as PERCENT, 
    al.AU_TIME as LOG_DATE, 
    req.RQ_USER_03 as APP, 
    req.RQ_REQ_ID as REQ_ID 
FROM AUDIT_PROPERTIES ap, 
    AUDIT_LOG al, 
    REQ 
WHERE al.AU_ACTION_ID = ap.AP_ACTION_ID and 
     req.RQ_REQ_ID = al.AU_ENTITY_ID and 
     req.rq_req_date BETWEEN TO_DATE('05/02/2017','dd/mm/yyyy') AND TO_DATE('20/02/2017','dd/mm/yyyy') and 
     ap.AP_FIELD_NAME = 'RQ_USER_58' 

在此先感謝。

+1

我有「表」。您的樣本代碼有*三*表格。你真正的問題是什麼? –

+0

對不起我的英文不好,上面編輯。 – imi36

回答

0

這可以在單個聚合查詢中完成(無子查詢)。按req_idtrunc(log_date)分組,然後爲每個組選擇一條記錄。 req_idmax(log_date)每個組內的,即每一天內)是顯而易見的。然後使用first/last功能(keep (dense_rank...)。你需要照顧的只是一點點,如果有可能有完全相同的日期和時間(精確到秒),對於一個給定req_id兩行。

下面是做這件事,我把你的測試和演示目的的WITH條款提供的測試數據,但是這是查詢的一部分。

with 
    test_data (percent, log_date, app, req_id) as (
     select 55, to_date('2017-02-07 15:44:22', 'yyyy-mm-dd hh24:mi:ss'), 'HUO', 253333 
     from dual union all 
     select 63, to_date('2017-02-08 10:42:18', 'yyyy-mm-dd hh24:mi:ss'), 'CQS', 265265 
     from dual union all 
     select 75, to_date('2017-02-08 06:55:12', 'yyyy-mm-dd hh24:mi:ss'), 'CQS', 265265 
     from dual union all 
     select 84, to_date('2017-02-09 08:35:42', 'yyyy-mm-dd hh24:mi:ss'), 'CQS', 265265 
     from dual union all 
     select 40, to_date('2017-02-09 09:45:14', 'yyyy-mm-dd hh24:mi:ss'), 'PLK', 277777 
     from dual 
    ) 
-- End of test data (not part of the solution). SQL query begins BELOW THIS LINE 
select max(percent) keep (dense_rank last order by log_date)   as percent, 
     max(log_date)             as log_date, 
     max(app)  keep (dense_rank last order by log_date, percent) as app, 
     req_id 
from test_data 
group by req_id, trunc(log_date) 
order by log_date, req_id 
; 

PERCENT LOG_DATE APP REQ_ID 
------- ---------- --- ------- 
    55 2017-02-07 HUO 253333 
    63 2017-02-08 CQS 265265 
    84 2017-02-09 CQS 265265 
    40 2017-02-09 PLK 277777 

4 rows selected. 
0

這樣做的典型方法是使用row_number()。最好的,我可以在你的情況下猜測:

select a.* 
from (select a.*, 
      row_number() over (partition by req_id order by log_date desc) as seqnum 
     from atable a 
    ) a 
where seqnum = 1; 
+0

*每日期*在敘述中,以及提供的測試數據和期望的結果,表明OP希望'trunc(log_date)'成爲'partition by'和'req_id'的一部分。 – mathguy

0

您可以通過編寫內部查詢或創建一箇中間表,通過只是時間組的數據做計算每個日期 內部查詢會看的MAX_TIME像這樣:

SELECT cast(al.AU_TIME as date) as LOG_DATE, 
max(al.AU_TIME) as max_LOG_TIME 
FROM AUDIT_PROPERTIES ap, 
    AUDIT_LOG al, 
    REQ 
WHERE al.AU_ACTION_ID = ap.AP_ACTION_ID and 
     req.RQ_REQ_ID = al.AU_ENTITY_ID and 
     req.rq_req_date BETWEEN TO_DATE('05/02/2017','dd/mm/yyyy') AND TO_DATE('20/02/2017','dd/mm/yyyy') and 
     ap.AP_FIELD_NAME = 'RQ_USER_58' 
GROUP BY LOG_DATE 

再查詢外層的需要與時間戳值這個內部查詢結合,以獲得只是這些記錄

Select TO_NUMBER(RTRIM(ap.AP_NEW_VALUE,'%')) as PERCENT, 
     al.AU_TIME, 
     req.RQ_USER_03 as APP, 
    req.RQ_REQ_ID as REQ_ID 
    FROM AUDIT_PROPERTIES ap 
    inner join (
SELECT cast(al.AU_TIME as date) as LOG_DATE, 
max(al.AU_TIME) as max_LOG_TIME 
FROM AUDIT_PROPERTIES ap, 
    AUDIT_LOG al, 
    REQ 
WHERE al.AU_ACTION_ID = ap.AP_ACTION_ID and 
     req.RQ_REQ_ID = al.AU_ENTITY_ID and 
     req.rq_req_date BETWEEN TO_DATE('05/02/2017','dd/mm/yyyy') AND TO_DATE('20/02/2017','dd/mm/yyyy') and 
     ap.AP_FIELD_NAME = 'RQ_USER_58' 
GROUP BY LOG_DATE) 
AS X 
ON ap.AU_TIME= X.max_LOG_TIME 
INNER JOIN AUDIT_LOG al 
on al.AU_ACTION_ID = ap.AP_ACTION_ID 
INNER JOIN REQ 
ON req.RQ_REQ_ID = al.AU_ENTITY_ID 
WHERE req.rq_req_date BETWEEN TO_DATE('05/02/2017','dd/mm/yyyy') AND TO_DATE('20/02/2017','dd/mm/yyyy') and 
     ap.AP_FIELD_NAME = 'RQ_USER_58' 
相關問題