Группировка SQL с несколькими критериями столбца

У меня есть таблица, как показано ниже. GiverID и TakerID являются внешними ключами к другой таблице, скажем, таблице Person. GiverID и TakerID не будут совпадать в пределах строки.

ID  GiverPersonID  TakerPersonID  Amount
 1              1              3     100
 2              2              1     200
 3              2              3     400
 4              3              2     800

Первая строка для этой таблицы означает, что человек с идентификатором 1 дает 100 человеку с идентификатором 3.

Мне нужен запрос, чтобы получить результат, как показано ниже

PersonID     TotalAmount
       1             100
       2             200
       3            -300

В основном, вычисляя окончательную сумму каждого человека. Для человека с ID 1 он дает 100 человеку с ID 3, но берет 200 у человека с ID 2, поэтому его окончательная сумма составляет 200 - 100, что равно 100.

Я читал о повороте, но я думаю, что поворот - не правильный шаг.

Каков эффективный SQL для вычисления этого результата?

ваш вопрос слишком неясен

Fahmi 29.05.2019 09:35

Действительно ли желаемый результат соответствует данным выборочной таблицы? Опишите, как вы рассчитываете каждое значение TotalAmount.

jarlh 29.05.2019 09:38
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
2
2
44
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Попробуй это-

SELECT 
CASE 
    WHEN A.GiverPersonID IS NULL THEN B.TakerPersonId 
    ELSE A.GiverPersonID
END PersonID, 
B.Take - A.Give TotalAmount
FROM
(
    SELECT GiverPersonID, SUM(Amount)  Give
    FROM your_tabel A
    GROUP BY GiverPersonID
)A
FULL JOIN
(
    SELECT TakerPersonId, SUM(Amount)  Take
    FROM your_tabel A
    GROUP BY TakerPersonId
) B
ON A.TakerPersonId= B.TakerPersonId

Выход-

PersonID    TotalAmount
1           100
2           200
3           -300
Ответ принят как подходящий
select user_id, sum(amount) from 
(
  select TakerPersonID as user_id, sum(amount) as amount
  from stack56355221
  group by 1
  union all
  select GiverPersonID, sum(-amount)
  from stack56355221
  group by 1
) as t1
group by 1

Выход:

1 100 
2 200 
3 -300

Если вам нужно все людей, а не только тех, кто есть в таблице, вы можете попробовать:

select p.*,
       (select sum(case when p.PersonId = t.GiverPersonID then t.amount else - t.amount end)
        from t
        where p.PersonId in (t.GiverPersonID, t.takerPersonID)
       ) as net_amount
from persons;

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