SQL查询:选择值低于阈值的最后一条记录

时间:2012-06-27 14:24:36

标签: sql database sybase

鉴于此示例数据集:

-----------------------------
| item   | date       | val |
-----------------------------
| apple  | 2012-01-11 |  15 |
| apple  | 2012-02-12 |  19 |
| apple  | 2012-03-13 |   7 |
| apple  | 2012-04-14 |   6 |
| orange | 2012-01-11 |  15 |
| orange | 2012-02-12 |   8 |
| orange | 2012-03-13 |  11 |
| orange | 2012-04-14 |   9 |
| peach  | 2012-03-13 |   5 |
| peach  | 2012-04-14 |  15 |
-----------------------------

我正在寻找每个项目的查询, 它将选择第一个日期,其中 val 低于 CONST = 10 ,而不会在之后返回上方。在这个例子中将是:

-----------------------------
| item   | date       | val |
-----------------------------
| apple  | 2012-03-13 |   7 |
| orange | 2012-04-14 |   9 |
-----------------------------

如果不使用游标,这是否可行?我正在Sybase中寻找这个。

如果没有游标这是不可能的,我可以用编程语言处理记录。但是,在那种情况下,因为在我的实际用例中,完整的历史记录很长,我需要一个“合适的”查询,只选择“足够”的记录来计算我最终记录的记录: val的最新记录低于 CONST 而不回到它之上。

2 个答案:

答案 0 :(得分:3)

这将返回详细的结果集。

select tablename.* from tablename
inner join 
(
    select tablename.item, min(tablename.[date]) as mindate 
                from tablename
        inner join (
                        select 
                             item, 
                             max([date]) lastoverdate 
                        from tablename 
                        where val>@const 
                        group by item
                               ) lastover
        on tablename.item = lastover.item
        and tablename.[date]> lastoverdate
    group by tablename.item
) below
    on tablename.item = below.item
    and tablename.date = below.mindate

答案 1 :(得分:1)

对于MySql:

select t.item, t.date1, t.val
from 
(
  select min(date) date1, item from tablename  t
  where not exists (select 1 from tablename where item = t.item 
                    and date1 > t.date1 and val >= 10)
and val < 10
  group by item
) a
inner join 
@t t
on a.item = t.item and a.date1 = t.date1

对于不同的数据库,例如MS-sql 2005 +:

select item, date, val from 
(
  select *, row_number() over (partition by item order by date) rn
  from tablename t
  where not exists (select 1 from @t where item = t.item and 
                    date > t.date and val >= 10)
  and val < 10
) a where rn = 1