我想找到一个上升,然后一个接一个。使用SQL

时间:2014-06-23 05:34:54

标签: mysql sql oracle postgresql

我认为这个问题持续一周。

无论如何。我想找到一个上升,然后一个接一个。使用SQL。

例如

此表存在。

name: ValTable



No  val  
1  → 2  
2  → 3  
3  → 2  
4  → 4  
5  → 3  
6  → 3  
7  → 4  
8  → 3  
9  → 2  
10 → 0 

应用两点。

① No.1-3 → 2,3(+1),2(-1)  
② No.6-8 → 3,4(+1),3(-1)

是否可以使用SQL执行?
(Oracle, Posgresql, MySQL
如果已知第一个数字就足够了。

或者我应该改变表结构和好的建议

4 个答案:

答案 0 :(得分:2)

SELECT t1.val first, t2.val second, t3.val third
FROM test t1
JOIN test t2 ON t2.no = t1.no + 1 AND t2.val = t1.val + 1
JOIN test t3 ON t3.no = t2.no + 1 AND t3.val = t1.val

http://www.sqlfiddle.com/#!2/02685/7

答案 1 :(得分:1)

在Postgres和Oracle中,您可以使用lead()函数:

select t.*
from (select t.*, lead(val) over (order by no) as val1, lead(val, 2) over (order by no) as val2
      from table t
     ) t
where val1 = val + 1 and val2 + val;

不幸的是,MySQL不支持这种ANSI标准功能,尽管你可以用连接来模仿它。

答案 2 :(得分:0)

在Oracle中,你可以获得

SELECT t1.val VAL1, t2.val VAL2, t3.val VAL3
FROM valTable v1, valTable v2, valTable v3
WHERE V1.NO = (V2.NO + 1)
AND   V1.VAL = (V2.VAL + 1)
AND   V2.NO = (V3.NO + 1)
AND   V2.VAL = (V3.VAL + 1)

答案 3 :(得分:0)

分析功能很容易。 LEAD和LAG允许我们使用结果集中下一行和前一行的值。

像这样(在Oracle中):

with vals as (
    select id as curr_id
           , lag(id) over (order by id) prev_id
           , lead(id) over (order by id) next_id
           , val as curr_val
           , lag(val) over (order by id) prev_val
           , lead(val) over (order by id) next_val
    from valtable
   )
   , diffs as (
   select prev_id 
          , next_id
          , prev_val
          , curr_val
          , next_val
          , ( curr_val - prev_val ) as prev_diff
          , ( next_val - curr_val ) as next_diff
  from vals )
select 
       *
from diffs
where prev_diff = 1
and next_diff = -1
;

作为奖励,SQL Fiddle包含所需的输出格式。 Check it out