我有一张表格,其中我必须报告当前状态以及此状态适用的日期。 例如:
Status date
1 26 July
1 24 July
1 22 July
2 21 July
2 19 July
1 16 July
0 14 July
鉴于此,我想将当前状态显示为1,将日期显示为7月22日>我不知道该怎么做。
Status date
1 25 July
1 24 July
1 20 July
在这种情况下,我想将状态显示为1,将日期显示为7月20日
答案 0 :(得分:1)
这应该使用非常标准的SQL来提取你需要的东西:
-- Get the oldest date that is the current Status
select Status, min(date) as date
from MyTable
where date > (
-- Get the most recent date that isn't the current Status
select max(date)
from MyTable
where Status != (
-- Get the current Status
select Status -- May need max/min here for multiple statuses on same date
from MyTable
where date = (
-- Get the most recent date
select max(date)
from MyTable
)
)
)
group by Status
我假设date
列是适合正确排序的数据类型(不是字符串,除非你可以强制转换)。
答案 1 :(得分:0)
这有点不合适,但应该有效
SELECT status, date
FROM my_table t
WHERE status = ALL (SELECT status
FROM my_table
WHERE date = ALL(SELECT MAX(date) FROM my_table))
AND date = ALL (SELECT MIN(date)
FROM my_table t1
WHERE t1.status = t.status
AND NOT EXISTS (SELECT *
FROM my_table t2
WHERE t2.date > t1.date AND t2.status <> t1.status))
答案 2 :(得分:0)
另一种选择是使用像LEAD
(或LAG
这样的窗口函数,具体取决于您如何订购结果)。在此示例中,我们在状态随日期更改时标记行,对结果进行排序并排除第一行以外的行:
with test_data as (
select 1 status, date '2012-07-26' status_date from dual union all
select 1 status, date '2012-07-24' status_date from dual union all
select 1 status, date '2012-07-22' status_date from dual union all
select 2 status, date '2012-07-21' status_date from dual union all
select 2 status, date '2012-07-19' status_date from dual union all
select 1 status, date '2012-07-16' status_date from dual union all
select 0 status, date '2012-07-14' status_date from dual)
select status, as_of
from (
select status
, case when status != lead(status) over (order by status_date desc) then status_date else null end as_of
from test_data
order by as_of desc nulls last
)
where rownum = 1;
<强>附录:强>
LEAD
和LAG
函数接受另外两个参数:offset
和default
。 offset
默认为1,default
默认为null。默认允许您确定在结果集的开头或结尾时要考虑的值。在您从未更改状态的情况下,需要默认值。在这个例子中,我提供-1作为状态默认值,因为我假设状态值不是预期集的一部分:
with test_data as (
select 1 status, date '2012-07-25' status_date from dual union all
select 1 status, date '2012-07-24' status_date from dual union all
select 1 status, date '2012-07-20' status_date from dual)
select status, as_of
from (
select status
, case when status != lead(status,1,-1) over (order by status_date desc) then status_date else null end as_of
from test_data
order by as_of desc nulls last
)
where rownum = 1;
您可以使用案例条件(等于/不等于),前导函数中的order by子句以及满足您需求的所需默认值。