1

我不知道我是否正确地措辞了这个问题,但它就是这样。

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

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

项目

  • item_id 名称
  • 活动状态
  • ETC

任务

  • task_id
  • item_id
  • 活动状态
  • 进度状态
  • ETC

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

  • 如果项目状态被取消或暂停...返回项目活动状态
  • 如果没有任务,返回 Completed
  • 如果所有任务都处于活动状态且未被取代,则
  • ...如果所有任务都未开始,则返回未开始
  • ...如果所有任务都已完成,则返回已完成
  • ...如果所有任务都处于暂停状态,则返回暂停
  • 否则返回 Started

我想使用 SQL 执行此操作并将其映射到我的休眠映射文件中的一个字段。

在过去的几天里,我尝试了很多东西,但似乎无法使其正常工作。我尝试对记录进行分组,如果找到 1 条记录,则返回该状态。我用过解码、大小写等。

以下是我尝试过的一些示例。在第二个示例中,我收到“不是单个组组功能”错误。

有什么想法吗?

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)
4

2 回答 2

0

如果您正在使用注释,则可以将@Formula("sql query here")其用于派生属性。有关(令人惊讶的简短)解释,请参阅Hibernate 公式文档

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

我建议将状态计算加入到您用来生成列表的任何查询中(大概在 NamedQuery 中)。这使您的数据库可以完成所有繁重的工作而不会被网络减慢,这是它最擅长的。Hibernate 文档提供了很多有用的查询示例,您可以尝试。

于 2013-08-23T16:20:15.927 回答
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
)
;
于 2013-08-23T16:13:18.193 回答