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