首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比较上一行的值以执行当前行SQL的计算。

比较上一行的值以执行当前行SQL的计算。
EN

Stack Overflow用户
提问于 2019-07-31 20:29:22
回答 1查看 73关注 0票数 0

sql小提琴:http://sqlfiddle.com/#!4/a717b/1

这是我的桌子:

这是我的密码:

select key, status, dat, sysdat, (case when key = 1 and type = 'Car' status = 'F' then round( sysdat-dat,2) else 0 end ) as Days, (case when key = 1 and type ='Bus' and Status = 'F' then round( sysdat-dat,2) else 0 end) as Days from ABC

预期产出:

因此,我想为以下条件计算'dat‘列和当前日期之间的天数。

1)对于每一把钥匙,顺序总是以汽车第一,公共汽车第二。这意味着,对于每一个钥匙,只有当汽车的状态是真实的,我们检查公共汽车。

2)如果“汽车”的状态是“T”,那么我不想计算天数

3)如果“汽车”的状态是“F”,那么我只想计算“汽车”的天数,而不计算“公共汽车”的天数,因为它总是“汽车”第一辆“公共汽车”的第二辆。

4)如果'Bus‘的状态是'F’,'Car‘的状态是'T’,那么我计算出的天数是因为它符合条件:'Car‘第一,'Bus’第二。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-31 20:53:10

带2辆车的

如果你总是有一辆车和一辆公共汽车,而且只有一辆车和一辆钥匙相同的公共汽车,你可以自己加入这个表,并检查车辆a (你正在查询的)是否是状态为F的汽车,或者相关的verhicle,b,是否是一辆状态为T的汽车。在这两种情况下,你都会得到一个约会,而在其他情况下,你没有。这包括了你的例子,还意味着如果汽车和巴士都是T,那么日期仍然只显示在巴士旁边。

代码语言:javascript
复制
select a.key, a.type, a.status, a.dat,
  case when 
    (a.type = 'car' and a.Status = 'F') or -- a is a car and is F
    (b.type = 'car' and b.Status = 'T') -- a is related to a car (b), which is T
  then
    trunc(sysdate) - a.dat
  end as DAYS
from 
  ABC a
  join ABC b on b.key = a.key and b.type <> a.type
order by
  -- Sort the query by key first, then type.
  a.key, 
  decode(a.type, 'car', 1, 2)

上面的查询:http://sqlfiddle.com/#!4/a717b/5/0

带N台车辆

如果你有更多的车辆,一种不同的方法可以更好,特别是当车辆数量很高,或没有固定。

下面的查询包含所有车辆及其排序顺序的列表。这是一个内联视图,但是您可以使用单独的查找表。查找表甚至更灵活,因为您只需添加车辆类型或更改其排序顺序。

无论如何,可以将该查找表/视图连接到您的主表上,以便为您的每条记录排序。

然后,您可以使用窗口函数(如rankdense_rank )进行排序,以引入基于排序顺序("falsenumber")的编号,以及状态为'F‘的事实。在此之后,很容易将日期放在第一行,即F (falsenumber = 1)。

代码语言:javascript
复制
with
  VW_TYPES as
  -- This could be a lookup table as well, instead of this hard-codeslist of unions.
  ( select 'car' as type, 1 as sortorder from dual union all
    select 'bus' as type, 2 as sortorder from dual union all
    select 'train' as type, 3 as sortorder from dual union all
    select 'airplane' as type, 4 as sortorder from dual union all
    select 'rocket' as type, 5 as sortorder from dual),

  VW_TYPESTATUS as
  ( select
      a.*,
      t.sortorder,
      dense_rank() over (partition by key order by case when a.status = 'F' then t.sortorder end) as falsenumber
    from
      ABC a
      join VW_TYPES t on t.type = a.type)

select
  ts.key, ts.type, ts.status, ts.dat, 
  case when ts.falsenumber= 1 then
    trunc(sysdate) - ts.dat
  end as DAYS
from
  VW_TYPESTATUS ts
order by
  ts.key, ts.sortorder

上面的查询:http://sqlfiddle.com/#!4/71f52/8/0

单独表中的车辆类型:http://sqlfiddle.com/#!4/f055d/1/0

请注意,oracle是区分大小写的。'car‘和'Car’和'CAR‘不是一回事。如果希望允许lower(type) = 'car'包含带有任何大小写的车辆类型,请使用type。请注意,这对使用索引是不好的,尽管我认为影响并不那么严重,因为每个键只有几行。

或者(可以说更好),您可以在新类型表中引入一个数字VehicleTypeId,并在ABC表中使用这个id,而不是字符串'Car‘。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57298400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档