坚持使用sql / hql查询组

时间:2012-11-06 09:10:48

标签: java sql oracle hql

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状态。从上面的示例中,结果查询应该具有:

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

这意味着只有最后一个SUCCESS状态按日期列update_finished和每个device_id的所有PENDING状态。

目前我正试图搞乱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的最后SUCCESS状态,但它错过了PENDING状态,并且没有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});

3 个答案:

答案 0 :(得分: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'

答案 1 :(得分: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' 

答案 2 :(得分: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问题中的样本数据。

然后,查询q1获取每条记录的最大更新日期,其中包含具有相同device_id和cojnfig_status的所有记录的集合。

查询q2然后计算另一个标志以决定是保留还是丢弃记录。因此,它保留了每个具有PENDINGstatus的记录。但它只保留那些具有SUCCESS状态且最新更新完成日期的记录。

最后的查询只是使用过滤器来显示标记值为'keep'的记录,并忽略标记值为'discard'的记录。

希望这能澄清逻辑。

相关问题