如何组合多个查询?

时间:2013-09-16 18:18:22

标签: sql oracle

我需要结合两个结果集,我觉得我是如此接近,但只是不知道如何将这一切包装起来:

这是一个结果集较小的查询(给我非活动状态)

select max(set_date) as most_recent_inactive, key_value, statusid
from status_history
where base_table = 'userinfo'  
and statusid = 10 and set_date > to_date('2012-10-01', 'YYYY-MM-DD')
group by key_value,statusid

recent_inactive key_value statusid
2013-01-30  15  10
2013-06-04  261 10
2013-06-18  352 10
2012-10-04  383 10
2013-01-22  488 10
2013-03-04  711 10
2013-06-19  749 10
2013-03-05  806 10

使用小结果集的另一个查询(给我激活)

select max (set_date) as most_recent_active, key_value,statusid
from status_history
where base_table = 'userinfo'  
and statusid =11
group by key_value,statusid

recent_active key_value statusid
2002-01-01  3   11
2002-01-01  5   11
2002-01-01  14  11
2002-01-01  15  11
2002-01-01  21  11
2002-01-01  23  11
2002-01-01  25  11
2002-01-01  26  11

我希望将所有活动和非活动组合在一起,所以我将它们全部联合起来

select null as most_recent_active, max(set_date) as most_recent_inactive, key_value,statusid
from status_history
where base_table = 'userinfo'  
and statusid = 10 and set_date > to_date('2012-10-01', 'YYYY-MM-DD')
group by key_value,statusid
    UNION all
select max(set_date) as most_recent_active, null as most_recent_inactive, key_value,statusid
from status_history
where base_table = 'userinfo'  
and statusid = 11
group by key_value,statusid
order by key_value

recent_active recent_inactive key_value statusid
2002-01-01  null    3   11
2002-01-01  null    5   11
2002-01-01  null    14  11
null  2013-01-30    15  10
2002-01-01  null    15  11
2002-01-01  null    21  11
2002-01-01  null    23  11
2002-01-01  null    25  11
2002-01-01  null    26  11
2002-01-01  null    27  11
2002-01-01  null    29  1

问题是key_value 15重复。

值是正确的,但我希望该记录和所有后续重复项“展平”,第15行和所有其他匹配作为一个记录同时设置两个日期字段。

同样,我觉得我太近了,但我怎么把这一切包起来?

谢谢?

3 个答案:

答案 0 :(得分:3)

您可以使用CASE语句拆分哪些处于非活动状态,哪些处于活动状态。默认情况下,如果未满足的情况是NULL,那么您将得到您想要的。

select max(case when statusid = 10 then set_date end) as most_recent_inactive
     , max(case when statusid = 11 then set_date end) as most_recent_active
     , key_value
     , max(statusid) as statusid
  from status_history
 where base_table = 'userinfo'  
   and statusid in (10, 11)
 group by key_value, statusid

你在非活动状态下进行的日期有点奇怪但是如果你想限制只是把它放在CASE中的非活动日期:

select max(case when statusid = 10  
                      and set_date > to_date('2012-10-01', 'YYYY-MM-DD')
                     then set_date 
           end) as most_recent_inactive
     , max(case when statusid = 11 then set_date end) as most_recent_active
     , key_value
     , max(statusid) as statusid
  from status_history
 where base_table = 'userinfo'  
   and statusid in (10, 11)
 group by key_value, statusid

我假设如果某些东西既是活动的又是非活动的,你想要显示它是活动的。如果要将其显示为非活动状态,请使用min(statusid);如果要显示两者,则需要另一列...遵循相同的逻辑;使用CASE语句。如果您不想要,则完全从SELECT和GROUP BY子句中删除它。

答案 1 :(得分:1)

这假设您的非活动status_id始终小于您的活动status_id。如果存在其他可能的status_id值,则可能无效。

select max(most_recent_active), max(most_recent_inactive), key_value, min(status_id)
from (select null as most_recent_active, max(set_date) as most_recent_inactive, key_value,statusid
from status_history
where base_table = 'userinfo'  
and statusid = 10 and set_date > to_date('2012-10-01', 'YYYY-MM-DD')
group by key_value,statusid
    UNION all
select max(set_date) as most_recent_active, null as most_recent_inactive, key_value,statusid
from status_history
where base_table = 'userinfo'  
and statusid = 11
group by key_value,statusid
order by key_value)
group by key_value

答案 2 :(得分:0)

在联盟之后GROUP BY

SELECT MAX(active) As most_recent_active,  MAX(inactive) As most_recent_in_active,
       key_value, statusid
FROM
(SELECT null as active, set_date as inactive, key_value, statusid
 FROM status_history
 WHERE base_table = 'userinfo'  
       AND statusid = 10 and set_date > to_date('2012-10-01', 'YYYY-MM-DD')

    UNION ALL

 SELECT set_date as active, null as inactive, key_value, statusid
 FROM status_history
 WHERE base_table = 'userinfo'  
       AND statusid = 11)

 GROUP BY key_value, statusid
 ORDER BY by key_value