2012-11-06 40 views
3
id   device_id config_status update_finished 
1   5015001  SUCCESS  11-OCT-2012 
2   5015001  SUCCESS  23-OCT-2012 
3   5015001  PENDING  23-OCT-2012 
4   5015001  PENDING  23-OCT-2012 
5   5016222  PENDING  12-OCT-2012 
6   5016222  PENDING  22-OCT-2012 

嗨,以上是我的表與一些示例數據。我想實現的是獲取每個device_id的最後SUCCESS狀態(日期位於update_finished字段中)和所有PENDING狀態。從結果查詢上面的例子應該有:堅持與sql/hql查詢組

id   device_id config_status update_finished 
2   5015001  SUCCESS  23-OCT-2012 
3   5015001  PENDING  23-OCT-2012 
4   5015001  PENDING  23-OCT-2012 
5   5016222  PENDING  12-OCT-2012 
6   5016222  PENDING  22-OCT-2012 

因此,這意味着通過update_finished日期列每個DEVICE_ID所有懸而未決的狀態只有最後一個SUCCESS狀態和。

目前我正在試圖亂用GROUP BY:SELECT device_id, config_status, max(update_finished) AS "LastUpdate" from config_status WHERE config_status = 'SUCCESS' group by device_id, config_status

這僅返回每個成功最後確實狀態DEVICE_ID,但它忽略掛起的狀態和它沒有id列。如果我將id字段添加到GROUP BY,那麼無論如何分組將是id

任何人都可以幫助我正確的查詢嗎?它應該有子查詢嗎?最後,我需要把它作爲HQL,但我認爲它會非常類似於SQL。

編輯:

謝謝大家對我的幫助了。所有這些查詢都能正常工作,但大部分都符合@Remigio提供的查詢,因爲最容易將其轉換爲HQL查詢,該查詢返回參數化對象,而不僅僅是Object。

這是我與其他字段的工作HQL查詢我在最初的例子

List<ConfigStatus> statuses = getHibernateTemplate().find("select c from ConfigStatus c " + 
       "where (configStatus = 'SUCCESS' and updateFinished = (select max(updateFinished) from " + 
       "ConfigStatus c1 where c1.device.deviceId = c.device.deviceId and c1.configStatus = 'SUCCESS' and c1.configFile.configFileId = ?)) " + 
       "or configStatus = 'PENDING' and configFile.configFileId = ?", new Object[] {configFileId, configFileId}); 
+0

爲了利用分區分析功能,瞭解oracle版本非常重要。 – danihp

+0

@danihp嗨,Oracle數據庫版本是10.2 – Skyzer

+0

不錯,我引用了oracle文檔樣本和一個適合您查詢的版本。看我的(未測試)答案。 – danihp

回答

2

你可以試試這個查詢:

select * from device d 
where (config_status='SUCCESS' and update_finished = (select max(update_finished) from 
device d1 where d1.device_id = d.device_id and d1.config_status='SUCCESS')) 
or config_status='PENDING' 
+0

太棒了!這可以讓我很容易地將它變成HQL。我編輯我的帖子,回答 – Skyzer

1

基於省略oracle sample

SELECT last_name FROM 
    (SELECT last_name, ROW_NUMBER() OVER (ORDER BY last_name) R FROM employees) 
    WHERE R BETWEEN 51 and 100; 

YOUT查詢應該是:

select * from (
    SELECT device_id, config_status, update_finished AS "LastUpdate" , 
    ROW_NUMBER() OVER (ORDER BY update_finished desc) R 
    from config_status WHERE config_status = 'SUCCESS' 
) where R = 1 

EDITED

select device_id, config_status, update_finished 
from (
    SELECT device_id, config_status, update_finished , 
    ROW_NUMBER() OVER (ORDER BY update_finished desc) R 
    from config_status WHERE config_status = 'SUCCESS' 
) where R = 1 
union all 
SELECT device_id, config_status, update_finished 
from config_status WHERE config_status = 'PENDING' 
+0

嗨,對不起,我第一次得到數據庫版本錯誤。它實際上是版本11. 您上面的查詢返回: 'device_id:5015000'' status:SUCCESS'' last_update:24-OCT-12'' R:1' 不是我期待的。我會看這個例子 – Skyzer

+0

5015000不在你的樣本數據。我只寫了很難查詢的部分,你應該把它與所有其他行聯合起來。查看編輯的查詢。 – danihp

0
 

    --Try This: 

    with T_CONFIG_STATUS as (
     select 1 as id, 5015001 as DEVICE_ID, 'SUCCESS' as CONFIG_STATUS, TO_DATE('11-OCT-2012','DD-MON-YYYY') as update_finished from DUAL union 
     select 2, 5015001, 'SUCCESS', TO_DATE('23-OCT-2012','DD-MON-YYYY') from DUAL union 
     select 3, 5015001, 'PENDING', TO_DATE('23-OCT-2012','DD-MON-YYYY') from DUAL union 
     select 4, 5015001, 'PENDING', TO_DATE('23-OCT-2012','DD-MON-YYYY') from dual union 
     select 5, 5016222, 'PENDING', TO_DATE('12-OCT-2012','DD-MON-YYYY') from dual union 
     select 6, 5016222, 'PENDING', TO_DATE('22-OCT-2012','DD-MON-YYYY') from DUAL 
    ) 
    , q1 as (
     select id, DEVICE_ID, CONFIG_STATUS, UPDATE_FINISHED, 
     max(UPDATE_FINISHED) over(partition by DEVICE_ID, CONFIG_STATUS) as MAX_UPDATE_FINISHED  
     from T_CONFIG_STATUS 
    ) 
    , q2 as (
     select id, device_id, config_status, update_finished, max_update_finished, 
     case 
      when config_status='SUCCESS' and update_finished=max_update_finished then 'keep' 
      when config_status='PENDING' then 'keep' 
      else 'discard' 
     end as KEEP_RECORD 
     from q1 
    ) 
    select id, device_id, config_status, update_finished 
    from Q2 where KEEP_RECORD='keep' 
    order by id; 

所以,表t_config_status不過是一個虛表Skyzer的問題cntaining樣本數據。

查詢Q1然後得到每個記錄withtin了一套具有相同的DEVICE_ID和cojnfig_status所有記錄的最大更新日期。

查詢q2然後計算另一個標誌來決定是保留還是丟棄一條記錄。所以,它會保留每個有PENDINGstatus的記錄。但它只保留具有最新更新完成日期的SUCCESS狀態的記錄。

最後的查詢然後只是使用過濾器來呈現標記值爲'keep'的記錄,並忽略標記值爲'discard'的記錄。

希望能夠澄清邏輯。

+0

請提供一個解釋你的代碼。 –