2016-12-16 8 views
0

Я столкнулся проблемы, пытаясь закодировать следующий запрос:ROWNUM и DISTINCT в оракула

SELECT id, 
     contractnumber, 
     partyid, 
     entity, 
     product, 
     fecha 
FROM (
    SELECT DISTINCT (contractdet.id), 
     contractdet.contractnumber, 
     contractdet.partyid, 
     contractdet.entity, 
     contractdet.product, 
     contractdet.fecha, 
     ROWNUM AS rnumber 
    FROM contractdet 
    INNER JOIN contractcust ON contractcust.contractdet_id = contractdet.id 
    INNER JOIN customerdet ON customerdet.partyid = contractdet.partyid 
    WHERE TO_CHAR(contractdet.fecha, 'YYYYMM') <= TO_CHAR(ADD_MONTHS(TO_DATE(20160828, 'YYYYMMDD'), -3), 'YYYYMM') 
    AND contractdet.product = 'TC' 
    ORDER BY contractdet.id ASC 
) 
WHERE rnumber BETWEEN ? AND ? 
ORDER BY id 

я использую его в в куске кода Java для того, чтобы страницы процесса, повторите запрос и получение 1000 результатов каждый раз. Основная проблема, которую я испытываю, заключается в том, что порядок DISTINCT применяется только к интервалу I am in, а не ко всему набору результатов, поэтому он извлекает дублированные строки, когда я смешиваю вывод всех запросов, которые я сделал.

+0

Приложить определенные усилия для форматирования запроса. –

+6

'DISTINCT' *** НЕ *** функция. Он всегда применяется ко всем ** столбцам в вашем запросе. –

+2

Также: 'TO_DATE (20160828, ..)' неверно. 'to_date()' ожидает, что строка ('varchar') не является числом, и вам не нужно' to_date() 'там вообще. Выражение также может быть упрощено до 'ADD_MONTHS (DATE '2016-08-28', -3)' –

ответ

0

Можете ли вы использовать CTE в своем SQL на Java?

Вот пример:

with distinctRecords as (
    select distinct myCol, rownum rnum 
    from myTable 
    order by myCol 
) 
select * 
from distinctRecords 
where rnum between ? and ?; 
+0

То есть, фактически, что делает OP, когда они используют встроенный просмотр. Это все еще подзапрос (и тот, который не может быть неспособен, из-за наличия rownum) независимо от того, объявляете ли вы подзапрос в предложении with или в предложении from. – Boneist

0

Вы можете сделать что-то вроде этого:

with t as (
     <your subquery here without the `distinct`> 
    ) 
select t.* 
from (select t.*, 
      row_number() over (partition by id order by id) as seqnum 
     from t 
    ) t 
where seqnum = 1; 

Это будет выбрать одну произвольную строку на id. Вы можете контролировать, какая строка выбрана (скажем, самая старая или самая новая), изменив order by в подзапросе.