SQL оставляет только строки с числами, которые не суммируются с нулем
У меня следующая проблема: у меня есть таблица, в которой есть следующие значения:
- ID: ЗНАЧЕНИЕ
- 1: 900
- 2: -900
- 3: 900
- 4: 900
Я хотел бы сделать запрос, который "отменяет" строки, которые добавляют к нулю, например, 1 и 2 или 2 и 3 или 2 и 4, так что в конце я могу получить следующую таблицу значений
- 900
- 900
но НЕ их сумма (1800). Я хочу их отдельно, мне все равно, какой идентификатор он выберет, просто хочу, чтобы числа не добавлялись к нулю, спасибо!
Всем привет, спасибо за помощь, да, на самом деле я хотел бы посмотреть, есть ли решение в простом базовом SQL (ответ klin превосходен, но похоже, что он имеет нестандартную функцию Postgres), поэтому я пытался это сделать в Access причина в том, что однажды на работе кто-то пришел ко мне с этой проблемой (у какого-то финансового парня, вы знаете, у них самые странные требования), и я нашел способ сделать это в Excel и VBA, но мне было интересно если есть способ сделать это прямо на SQL, еще раз спасибо! и для комментария melpomene, нет, 400,500 и -900 не должны отменять, только пары с тем же значением, противоположный знак, спасибо.
1 ответ
Я предполагаю, что мы ищем пары строк с противоположными значениями.
Пример данных (Postgres).
create table test (id int, val int);
insert into test values
(1, 900), (2, -900), (3, 900), (4, 900),
(5, -400), (6, 400), (7, -400), (8, -400);
select * from test;
id | val
----+------
1 | 900
2 | -900
3 | 900
4 | 900
5 | -400
6 | 400
7 | -400
8 | -400
(8 rows)
Запрос:
delete from test
where id in (
select unnest(array[id1, id2])
from (
select distinct on (id1) *
from (
select t1.id id1, t2.id id2
from test t1
join test t2
on t1.val + t2.val = 0 and t1.id < t2.id and t1.val > 0
) s1
) s2
);
Результат:
select * from test;
id | val
----+------
3 | 900
4 | 900
5 | -400
8 | -400
(4 rows)
Вы можете попробовать запрос без специальных функций Postgres:
delete from test
where id in (
select id1
from (
select id1, min(id2) id2
from (
select t1.id id1, t2.id id2
from test t1
join test t2
on t1.val + t2.val = 0 and t1.id < t2.id and t1.val > 0
) s1
group by id1
) s2
union all
select id2
from (
select id1, min(id2) id2
from (
select t1.id id1, t2.id id2
from test t1
join test t2
on t1.val + t2.val = 0 and t1.id < t2.id and t1.val > 0
) s1
group by id1
) s3
);
Использовать общее табличное выражение (with
заявление) для подзапроса, если ваш сервер может принять это.