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 заявление) для подзапроса, если ваш сервер может принять это.

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