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 применяется только к интервалу, в котором я нахожусь, а не ко всему набору результатов, поэтому он извлекает дублированные строки, когда я смешиваю результаты всех выполненных мной запросов.

2 ответа

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

Вот пример:

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

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

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 в подзапросе.

Другие вопросы по тегам