如果所有子记录中的字段相同,如何选择字段值

时间:2013-08-23 15:17:06

标签: java sql oracle select

我不知道我是否正确地写了这个问题,但现在就这样了。

这是一个使用java,oracle,hibernate的Web应用程序。

我在一个(项目)到多个(任务)关系中有两个表。

产品

  • item_id name
  • active_status

任务

  • task_id
  • ITEM_ID
  • active_status
  • progress_status

项目的状态由其所有任务的状态组成。这是逻辑......

  • 如果项目状态已取消或暂停...返回项目活动状态
  • 如果没有任务,请返回已完成
  • 如果所有任务都处于活动状态且未被取代,则
  • ...如果所有任务都未启动,则返回未启动
  • ... return如果所有任务都已完成,则完成
  • ...如果所有任务都处于暂停状态,则返回保持状态
  • 否则返回

我想使用SQL并将其映射到我的hibernate映射文件中的字段。

过去几天我尝试过很多东西,似乎无法让它发挥作用。我尝试对记录进行分组,如果找到1条记录,则返回该状态。我用过decode,case等等。

以下是我尝试过的一些事例。在第二个例子中,我得到一个'不是单个组组函数'错误。

有什么想法吗?

select decode(i.active_status_id, 'OH', i.active_status_id, 'Ca', i.active_status_id,t.progress_status_id)
        from tasks t 
        LEFT OUTER JOIN Items i
                ON i.item_id = t.item_id
        where t.item_id = 10927815 and t.active_status_id = 'Ac' and t.active_status_id != 'Su' 
        group by i.active_status_id, t.progress_status_id;




select case                         
        when (count(*) = 1) then progress_status_id
        else 'St'
        end
        from 
        (select progress_status_id
                from tasks t 
                        where t.item_id = 10927815 and (t.active_status_id = 'Ac' and t.active_status_id != 'Su') group by t.progress_status_id)

2 个答案:

答案 0 :(得分:0)

也许是这样的

SELECT 
  item_id
, CASE 
    WHEN active_status IN ('Canceled', 'On Hold') THEN active_status
    WHEN t_num = 0 THEN 'Completed'
    WHEN flag_all_active = 1 AND flag_all_not_started = 1 THEN 'Not Started'
    WHEN flag_all_active = 1 AND flag_all_completed = 1 THEN 'Completed'
    WHEN flag_all_active = 1 AND flag_all_on_hold = 1 THEN 'On Hold'
  ELSE 'Started'
  END
FROM
(
  SELECT 
      i.item_id
    , i.active_status
    , sum(CASE WHEN t.task_id is NULL THEN 0 ELSE 1 end ) as t_num
    , MIN( CASE t.active_status WHEN 'Ac' THEN 1 ELSE 0 END ) as flag_all_active 
    , MIN( CASE t.progress_status_id WHEN 'Not Starten' THEN 1 ELSE 0 END ) as flag_all_not_started
    , MIN( CASE t.progress_status_id WHEN 'Completed' THEN 1 ELSE 0 END ) as flag_all_completed
    , MIN( CASE t.progress_status_id WHEN 'On Hold' THEN 1 ELSE 0 END ) as flag_all_on_hold

  FROM 
    items i
    left outer join tasks t on (t.item_id = i.item_id )
  group by i.item_id
)
;

答案 1 :(得分:0)

如果您正在使用注释,则可以使用@Formula("sql query here")作为派生属性。 请参阅Hibernate formula docs了解(令人惊讶的简短)解释。

或者,由于您正在处理相对较大的项目列表,因此最好将状态计算作为初始查询的一部分,从而避免数据库受到数百或数千个请求的攻击。如果迭代列表中的每个项目,可能会发生这种情况。

我建议将状态计算加入到用于生成列表的任何查询中(可能是在NamedQuery中)。这样,您的数据库就可以完成所有繁重的工作,而不会被网络放慢速度,这就是它最擅长的。 Hibernate docs提供了许多有用的查询示例。