Отсеивание записей для которых есть дубликат с минусом
От: _agg  
Дата: 26.01.22 09:44
Оценка:
Всем привет, я столкнулся с проблемой и пока немогу решить. Есть записи которые дублируются за исключением суммы, встречаются иногда пара записей у которых все поля идентичны кроме того что сумма со знаком минус в одной из записей,
к примеру:
...
|запись1|10 |
|запись1|-10|
|запись2|3 |
|запись3|7 |
...

Как мне с помощью SQL сделать такую выборку в которой нет записей для которых есть дубликат со знаком минус ?
Отредактировано 26.01.2022 9:45 _agg . Предыдущая версия .
Re: Отсеивание записей для которых есть дубликат с минусом
От: Olaf Россия  
Дата: 26.01.22 10:16
Оценка:
Здравствуйте, _agg, Вы писали:

_>Всем привет, я столкнулся с проблемой и пока немогу решить. Есть записи которые дублируются за исключением суммы, встречаются иногда пара записей у которых все поля идентичны кроме того что сумма со знаком минус в одной из записей,

_>к примеру:
_>...

_>Как мне с помощью SQL сделать такую выборку в которой нет записей для которых есть дубликат со знаком минус ?


Вы не сказали какая у вас СУБД. Но идея в реализации может быть следующая...
/* С оконными функциями */
select
    *
from
(
    select
        *
        ,count(*) over(partition by Name, abs(Value)) as Cnt
    from
    (
        values
            ('запись 1', 10),
            ('запись 1', -10),
            ('запись 1', 10),
            ('запись 2', 10),
            ('запись 2', -20),
            ('запись 2', -20),
            ('запись 3', 40),
            ('запись 3', 50)
    ) a (Name, Value)
) b
where
    cnt = 1

/* C join */
;with cte as 
(
    select
        Name, Value
    from
    (
        values
            ('запись 1', 10),
            ('запись 1', -10),
            ('запись 1', 10),
            ('запись 2', 10),
            ('запись 2', -20),
            ('запись 2', -20),
            ('запись 3', 40),
            ('запись 3', 50)
    ) a (Name, Value)
)
select
    c2.Name, c2.Value
from
    cte c1
join
    cte c2
on
    c1.Name = c2.Name and abs(c1.Value) = abs(c2.Value)
group by
    c2.Name, c2.Value
having
    count(*) = 1
Re: Отсеивание записей для которых есть дубликат с минусом
От: vmpire Россия  
Дата: 26.01.22 10:17
Оценка: +1
Здравствуйте, _agg, Вы писали:

_>Как мне с помощью SQL сделать такую выборку в которой нет записей для которых есть дубликат со знаком минус ?

Самое простое — кореллированный подзапрос во where
Re: Отсеивание записей для которых есть дубликат с минусом
От: wildwind Россия  
Дата: 26.01.22 10:33
Оценка:
Здравствуйте, _agg, Вы писали:

А если два раза плюс и один раз минус? А если сумма не совпадает?
Re: Отсеивание записей для которых есть дубликат с минусом
От: Maniacal Россия  
Дата: 26.01.22 10:44
Оценка:
Здравствуйте, _agg, Вы писали:

_>Всем привет, я столкнулся с проблемой и пока немогу решить. Есть записи которые дублируются за исключением суммы, встречаются иногда пара записей у которых все поля идентичны кроме того что сумма со знаком минус в одной из записей,

_>к примеру:
_>...
_>|запись1|10 |
_>|запись1|-10|
_>|запись2|3 |
_>|запись3|7 |
_>...

_>Как мне с помощью SQL сделать такую выборку в которой нет записей для которых есть дубликат со знаком минус ?


SELECT * FROM table1 t1 WHERE sum >=0 AND NOT EXISTS (SELECT 1 FROM table1 t2 WHERE t2.n=t1.n AND t2.sum<0)


Пример:
create table table1 (
    id SERIAL PRIMARY KEY,
    n VARCHAR(32),
    sum DOUBLE PRECISION
);

insert into table1 (n, sum) VALUES('запись1', 10);
insert into table1 (n, sum) VALUES('запись1', -10);
insert into table1 (n, sum) VALUES('запись2', 3);
insert into table1 (n, sum) VALUES('запись3', 7);


Вывод:

3 "запись2" 3
4 "запись3" 7

Re: Отсеивание записей для которых есть дубликат с минусом
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.01.22 12:21
Оценка:
Здравствуйте, _agg, Вы писали:

_>Всем привет, я столкнулся с проблемой и пока немогу решить. Есть записи которые дублируются за исключением суммы, встречаются иногда пара записей у которых все поля идентичны кроме того что сумма со знаком минус в одной из записей,

_>к примеру:
id amount
_>|запись1|10 |
_>|запись1|-10|
_>|запись2|3 |
_>|запись3|7 |
_>...

_>Как мне с помощью SQL сделать такую выборку в которой нет записей для которых есть дубликат со знаком минус ?


select * from records r where not exists select * from records inv where r.id = inv.id and r.amount = -inv.amount
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Отсеивание записей для которых есть дубликат с минусом
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.01.22 12:22
Оценка:
Здравствуйте, _agg, Вы писали:

_>Всем привет, я столкнулся с проблемой и пока немогу решить. Есть записи которые дублируются за исключением суммы, встречаются иногда пара записей у которых все поля идентичны кроме того что сумма со знаком минус в одной из записей,

_>к примеру:
_>...
_>|запись1|10 |
_>|запись1|-10|
_>|запись2|3 |
_>|запись3|7 |
_>...

_>Как мне с помощью SQL сделать такую выборку в которой нет записей для которых есть дубликат со знаком минус ?


А ещё я подозреваю, что это не "дубликаты", а сторнирующие проводки.
Может, вам надо
select id, sum(amount) from records group by id

?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Отсеивание записей для которых есть дубликат с минусом
От: TMU_2  
Дата: 27.01.22 10:00
Оценка:
_>>Всем привет, я столкнулся с проблемой и пока немогу решить. Есть записи которые дублируются за исключением суммы, встречаются иногда пара записей у которых все поля идентичны кроме того что сумма со знаком минус в одной из записей,
_>>к примеру:
_>>...
_>>|запись1|10 |
_>>|запись1|-10|
_>>|запись2|3 |
_>>|запись3|7 |
_>>...

_>>Как мне с помощью SQL сделать такую выборку в которой нет записей для которых есть дубликат со знаком минус ?


M>
M>SELECT * FROM table1 t1 WHERE sum >=0 AND NOT EXISTS (SELECT 1 FROM table1 t2 WHERE t2.n=t1.n AND t2.sum<0)
M>




В качестве придирки: если возможен случай, когда модули сумм не строго совпадают (ситуация похожа на некие проводки и их отмены, а возможна частичная отмена), то будет проблема.
Универсальнее, как и писали по соседству, вариант
SELECT * FROM table1 t1 WHERE sum >=0 AND NOT EXISTS (SELECT 1 FROM table1 t2 WHERE t2.n=t1.n AND -t2.sum=t1.sum)
Re[2]: Отсеивание записей для которых есть дубликат с минусом
От: Dym On Россия  
Дата: 30.01.22 20:32
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

_>>Как мне с помощью SQL сделать такую выборку в которой нет записей для которых есть дубликат со знаком минус ?


S>А ещё я подозреваю, что это не "дубликаты", а сторнирующие проводки.

S>Может, вам надо
S>
S>select id, sum(amount) from records group by id
S>

S>?
Ну и наверное добавить:
having sum(amount) <> 0
Счастье — это Glück!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.