Как найти дубликаты строк, в колонках которых содержатся значения null?
Исходная таблица:
Дублями считаются случаи:
Т. е дублями в исходной таблице являются строки 3-4, 5-6, 7-8, 9-10, 11-12.
Строки 1-2 в исходной таблице - не дубли.
Нужно получить все строки, кроме первых двух.
Нужный результат:

Структура таблицы:
create table transport (
id serial,
enginenumber varchar(10),
carcassnumber varchar(10)
);
insert into transport(enginenumber, carcassnumber) values('A', 'B');
insert into transport(enginenumber, carcassnumber) values('A', 'C');
insert into transport(enginenumber, carcassnumber) values('A', 'B');
insert into transport(enginenumber, carcassnumber) values('A', 'B');
insert into transport(enginenumber, carcassnumber) values('A', 'B');
insert into transport(enginenumber, carcassnumber) values('A', null);
insert into transport(enginenumber, carcassnumber) values('A', 'B');
insert into transport(enginenumber, carcassnumber) values(null, 'B');
insert into transport(enginenumber, carcassnumber) values('A', null);
insert into transport(enginenumber, carcassnumber) values('A', null);
insert into transport(enginenumber, carcassnumber) values(null, 'B');
insert into transport(enginenumber, carcassnumber) values(null, 'B');
Ответы (1 шт):
Задача выглядит странной, т.к. обычно в табличных данных нет привязки к следованию строк. Для простого запроса строки 1 и 3 будут одинаковые.
Если использовать аналитические функции, то в них можно обращаться к значением предыдущих/следующих строк.
select
rn, enginenumber, carcassnumber
from (
select
row_number() over w rn,
enginenumber, carcassnumber,
lag(enginenumber) over w lag_enginenumber, -- предыдущее значение
lag(carcassnumber) over w lag_carcassnumber,
lead(enginenumber) over w lead_enginenumber, -- следующее значение
lead(carcassnumber) over w lead_carcassnumber
from transport
window w as (order by id)) t
where (mod(t.rn, 2) = 1 and coalesce(t.enginenumber, t.lead_enginenumber, '') = coalesce(t.lead_enginenumber, t.enginenumber, '')
and coalesce(t.carcassnumber, t.lead_carcassnumber, '') = coalesce(t.lead_carcassnumber, t.carcassnumber, ''))
or
(mod(t.rn, 2) = 0 and coalesce(t.enginenumber, t.lag_enginenumber, '') = coalesce(t.lag_enginenumber, t.enginenumber, '')
and coalesce(t.carcassnumber, t.lag_carcassnumber, '') = coalesce(t.lag_carcassnumber, t.carcassnumber, ''));
Если строки следуют в порядке возрастания идентификаторов, то следующую/предыдущую строку можно искать через подзапрос и сравнение с минимальным/максимальным идентификатором относительно текущего.

