1

I need to combine two result sets and I feel I am so close but just don't see how to wrap this all up:

Here's one query with a small result set, (give me inactives)

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

Output:

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

Another query with a small result set (give me actives)

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

Output:

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

I want to get all of the actives and inactives together, so I union them all

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

Output:

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

The problem is key_value 15 is duplicated.

The values are correct, but i want that record and all subsequent duplicates "flattened," row 15 and all other matches coming through as one record with both date fields set.

Again, I feel I'm so close but how do I wrap this all up?

Thank you?

4

3 回答 3

3

You can use a CASE statement to split out which are inactive and which are active. The default, if the case is not fulfilled is NULL so you'll get what you want.

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

The date thing you've got going on in the inactive is a little strange but if you want to restrict just put this in the CASE for inactive dates:

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

I've assumed that if something is both active and inactive you want to display that it's active. If you want to display it as inactive use min(statusid); if you want to display both then you need another column... follow the same logic; use a CASE statement. If you want neither then remove it from the SELECT and GROUP BY clauses completely.

于 2013-09-16T18:24:51.573 回答
1

这是假设您的非活动状态 ID 始终小于您的活动状态 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
于 2013-09-16T18:29:52.690 回答
0

Do GROUP BY after the union.

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
于 2013-09-16T18:24:51.967 回答