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});
答案 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)
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'的记录。
希望这能澄清逻辑。