根据另一个表

时间:2015-06-30 22:34:50

标签: sql oracle11gr2 listagg

我需要向注册活动的用户发送数据。当状态被删除或添加到与组关联的状态列表时,会发生这些事件。

某些上下文:我的数据有组,每个组都有一个名为sublead状态的状态列表。组可以根据需要/需要拥有尽可能多的子状态。

因此,第1组可以将IA,WY和NY作为subleads,或者它可以只有IA,或者它可以没有。

我的问题涉及3个不同的表格。

  • 名为group_sublead_state的表格,其中包含属于某个组的每个子项目状态的条目
  • 一个名为sublead_state_audit的审核表,其中包含有关在组中添加或删除子级别状态的信息
  • 名为sublead_change_results的表格将在用户电子邮件中显示,当他们订阅的状态被删除或添加到组子栏状态列表中时(此表格应该是我查询的结果。我无法创建此表,执行插入,删除或更新。这严格地说是一个很长的丑陋的选择查询的结果,它将其他两个表混合在一起,还有一些表包含其他信息,如组名等等(其他表格不相关))

以下是包含一些数据的表格:

group_sublead_state

group_id    state
1           IA
1           WY
2           NY
2           OH
2           NV

这张表告诉我们有两组,一组有两个无效状态,一组有三个无效状态

这里是sublead_state_audit表

group_id    state_added    state_removed
1           none           MO
1           IA             none
2           NY             none
2           OH             none
2           none           CA

我们从审计表中看到最近的变化是

  • group_id 1删除了MO,并添加了IA
  • group_id 2添加了NY和OH,并删除了CA

所以sublead_change_results表必须如下所示

group_id    old_states    new_states
1           MO,WY         IA,WY
2           CA,NV         NY,OH,NV

所以new_states列非常简单,我已经使用LISTAGG函数完成了它(我们将为每个组current_state_list调用该列表)。 old_states列虽然......这是我需要帮助的地方。

我必须使用这些表中的资源来编译old_states列中的逗号分隔列表。到目前为止,我的想法是尝试使用已经为new_states列构建的逻辑。因此,对于每个group_id,我将从current_states_list表的state_added列中的sublead_state_audit中删除状态;我会向current_states_list的state_removed列中的sublead_state_audit添加状态。

LISTAGG完全可以吗?还有其他方法可以吗?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我认为这可以满足您的需求:

select x.group_id,
       x.old_states,
       y.new_states
  from (select group_id,
               listagg(state, ',') within group(order by state) as old_states
          from (select group_id,
                       state_removed as state
                  from sublead_state_audit
                 where state_removed <> 'none'
                union all
                select group_id,
                       state
                  from group_sublead_state
                 where state not in (select state_added from sublead_state_audit))
         group by group_id) x
  join (select group_id,
               listagg(state, ',') within group(order by state) as new_states
          from group_sublead_state
         group by group_id) y
    on x.group_id = y.group_id;

小提琴: http://sqlfiddle.com/#!4/2921e/1/0