2016-09-07 2 views
0

У меня есть следующий запрос, где, если дата редактирования не равна нулю, тогда необходимо вернуть последнюю запись, а также быть рандомизированной, иначе записи должны быть рандомизированы , Я попробовал следующий порядок, но я получаю недостающую ошибку ключевого слова.ORA-00905: отсутствует ключевое слово при использовании примера в порядке

SELECT * FROM (SELECT c.id,c.edit_date, c.name,l.title 
              FROM tableA c, tableb l 
             WHERE c.id = l.id 
              AND c.published_ind = 'Y' 
              AND lc.type_id != 4 
              AND TRIM(c.img_file) IS NOT NULL 
             ORDER BY DBMS_RANDOM.VALUE 
            ) 
         WHERE ROWNUM = 1 

    order by case when c.edit_date = 'null' 
      then DBMS_RANDOM.VALUE 
      else DBMS_RANDOM.VALUE, c.edit_date desc 
    end 
+1

Выражение case возвращает одно значение. Он не используется для условного выполнения кода. – jarlh

+0

@jarlh - Я не вижу «условного исполнения» в любом месте, я просто вижу выражение 'case', используемое в предложении' order by'. Это допустимое использование. – mathguy

+0

@mathguy, \t Кажется, что OP хочет сортировать по DBMS_RANDOM.VALUE (когда c.edit_date = 'null'), или по DBMS_RANDOM.VALUE, c.edit_date desc. То есть либо одной, либо другой. Какое-то условное исполнение. – jarlh

ответ

1

Если я вас правильно, вы пытаетесь получить запись на ID или с самой высокой датой (случайной один, если несколько записей с одинаковой датой существует) или с датой NULL (опять случайные один, когда более NULL записи с тем же идентификатором не существует.

Так предполагая эти данные

 ID EDIT_DATE   TEXT 
---------- ------------------- ---- 
     1 01.01.2015 00:00:00 A  
     1 01.01.2016 00:00:00 B  
     1 01.01.2016 00:00:00 C  
     2 01.01.2015 00:00:00 D  
     2 01.01.2016 00:00:00 E  
     2      F  
     2      G 

Вы ожидаете либо B или C для ID = 1 и либо F или G для ID = 2.

Этот запрос сделать Это. Функция используется упорядоченности с NULLS ПЕРВЫХ и добавляющей случайное значение в качестве последнего заказа столбца - получить случайный результат, если все столбцы, предшествующие же ..

with dta as (
select 1 id, to_date('01012015','ddmmyyyy') edit_date, 'A' text from dual union all 
select 1 id, to_date('01012016','ddmmyyyy') edit_date, 'B' text from dual union all 
select 1 id, to_date('01012016','ddmmyyyy') edit_date, 'C' text from dual union all 
select 2 id, to_date('01012015','ddmmyyyy') edit_date, 'D' text from dual union all 
select 2 id, to_date('01012016','ddmmyyyy') edit_date, 'E' text from dual union all 
select 2 id, NULL edit_date, 'F' text from dual union all 
select 2 id, NULL edit_date, 'G' text from dual), 
dta2 as (
select ID, EDIT_DATE, TEXT, 
row_number() over (partition by ID order by edit_date DESC NULLS first, DBMS_RANDOM.VALUE) as rn 
from dta) 
select * 
from dta2 where rn = 1 
order by id 
; 

     ID EDIT_DATE   TEXT   RN 
---------- ------------------- ---- ---------- 
     1 01.01.2016 00:00:00 B    1 
     2      F    1 

Надеется, вы можете повторно использовать идея, если вам нужен немного другой результат ...

+0

спасибо за ваши материалы, я все еще пытаюсь понять это, любые идеи будут оценены. Таким образом, каждый ID будет иметь только 1 запись, если edit_dt не является нулевым, то я хочу, чтобы сначала получить эту запись, это возможно. Мне нужно всего лишь 1 строка из набора результатов, и она должна быть рандомизирована. это то, что делает первоначальный запрос. Теперь мне нужно определить дату редактирования в запросе и сделать это - получить последнее обновление и самую новую запись сначала во время ротации. Предварительно – user747291

+0

@ user747291 Я перечитываю ваш комментарий несколько раз, но я не уверен, если я удержу его. Возможно, вы могли бы предоставить пример данных с ожидаемыми результатами (больше результатов, которые иллюстрируют случайность). –

0

Ведомость WHERE всегда применяется перед заявлением ORDER BY. Поэтому в вашем запросе сначала будет применен WHERE ROWNUM = 1 и только после этого будет применен order by case ... для одной записи. Возможно, вам понадобится добавить еще один подзапрос, который сначала выполнит ORDER BY, получите набор строк в правильном порядке и после этого выполните WHERE ROWNUM = 1, чтобы выбрать одну строку.

Статус ORDER BY ... DBMS_RANDOM.VALUE, c.edit_date выглядит странно. Фактически, набор записей будет отсортирован по DBMS_RANDOM.VALUE, и если rowset имеет пару строк, равные DBMS_RANDOM.VALUE, мы будем сортировать их по c.edit_date.

 Смежные вопросы

  • Нет связанных вопросов^_^