получить только строку, которая удовлетворяет условию, если такая строка существует, и если нет, получить строку, которая удовлетворяет другому условию - PullRequest
0 голосов
/ 25 декабря 2018

это звучит как простой вопрос, но я просто не могу найти правильный путь.с учетом упрощенной таблицы

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, orderdate строки, где rn = 1 (строка, где rn = 1 гарантированно существует в таблице). Учитывая приведенные выше требования, что мне нужно поместить впредложение, чтобы получить следующее?

desirable output

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

Здесь 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
)
0 голосов
/ 25 декабря 2018

Вы можете использовать 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...