如果存在这样的行,则仅获得满足条件的行;如果不存在,则仅获得满足另一条件的行

时间:2018-12-25 10:43:47

标签: sql oracle oracle10g

这听起来像是一个简单的问题,但我只是找不到正确的方法。 给出简化表

with t as  (
select   ordernumber, orderdate,  case when ordertype in (5,21) then 1 else 0 end is_restore , ordertype, row_number() over(order by orderdate) rn from
( 
select to_date('29.08.08','DD.MM.YY') orderdate,'313' ordernumber, 1  as ordertype  from dual union all
select to_date('13.03.15','DD.MM.YY') orderdate, '90/4/2' ordernumber, 5  as ordertype from dual
)
)
select * from t -- where clause  should be here 

Input data

每行is_restore保证为1或0。 如果表中有is_restore = 1的行,则选择订单号,该行的订单日期,然后再选择其他任何内容。 如果表中没有is_restore = 1的行,则选择ordernumber,rn = 1的行的orderdate(保证在表中存在rn = 1的行)  鉴于上述要求,我需要在where子句中获取以下内容?

desirable output

2 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER

CREATE TABLE t
AS
select ordernumber, orderdate,
    case when ordertype in (5,21) then 1 else 0 end is_restore, ordertype,
    row_number() over(order by orderdate) rn
  from ( 
     select to_date('29.08.08','DD.MM.YY') orderdate,'313' ordernumber,
           1  as ordertype 
     from dual union all
     select to_date('13.03.15','DD.MM.YY') orderdate, '90/4/2' ordernumber,
            5  as ordertype
     from dual);

-------------------

with cte as (
  select t.*,
    ROW_NUMBER() OVER(/*PARTITION BY ...*/ ORDER BY is_restore DESC, rn) AS rnk
  from t
)
SELECT *
FROM cte
WHERE rnk = 1;

db<>fiddle demo

答案 1 :(得分:0)

这里是sql,它不使用窗口函数,对于那些数据库不支持OVER(...)或有索引字段(基于查询的数据库)的人来说,它可能会有用。

SELECT
* 
FROM t
WHERE t.is_restore = 1 
OR (
 NOT EXISTS (SELECT 1 FROM t WHERE t.is_restore = 1)
 AND t.rn = 1
)