比较值sql

时间:2012-07-27 16:06:08

标签: sql oracle

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

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日

3 个答案:

答案 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;

<强>附录: LEADLAG函数接受另外两个参数:offsetdefaultoffset默认为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子句以及满足您需求的所需默认值。