1

我有一个表格,我必须在其中报告当前状态以及此状态适用的日期。例子:

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 日

4

3 回答 3

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列是适合正确排序的数据类型(例如,不是字符串,除非您可以转换它)。

于 2012-07-27T16:57:29.337 回答
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 and函数接受 另外LAG两个参数:offsetand defaultoffset默认为 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; 

您可以使用 case 条件(等于/不等于)、前导函数中的 order by 子句以及满足您需求的所需默认值。

于 2012-07-27T17:04:08.907 回答
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))
于 2012-07-27T16:30:37.773 回答