Отдельные строки с суммированием

#sql-server #tsql

#sql-сервер #tsql

Вопрос:

У меня есть таблица РАСХОДОВ.

 DECLARE @EXPENSE TABLE
(
    ID INT,
    CURRENCY NVARCHAR(4),
    AMOUNT   MONEY
)

INSERT INTO @EXPENSE VALUES
(1,'USD',100),
(2,'USD',10),
(1,'USD',80),
(2,'USD',5),
(1,'EUR',80),
(1,'EUR',30),
(3,'USD',20)
  

Данные показаны ниже:

  ---- ---------- -------- 
| ID | CURRENCY | AMOUNT |
 ---- ---------- -------- 
| 1  | USD      | 100    |
 ---- ---------- -------- 
| 2  | USD      | 10     |
 ---- ---------- -------- 
| 1  | USD      | 80     |
 ---- ---------- -------- 
| 2  | USD      | 5      |
 ---- ---------- -------- 
| 1  | EUR      | 80     |
 ---- ---------- -------- 
| 1  | EUR      | 30     |
 ---- ---------- -------- 
| 3  | USD      | 20     |
 ---- ---------- -------- 
  

Я хотел бы получить такой результат.

  ---- ---------- -------- 
| ID | CURRENCY | AMOUNT |
 ---- ---------- -------- 
| 1  | EUR      | 110    |
 ---- ---------- -------- 
| 1  | USD      | 180    |
 ---- ---------- -------- 
| 2  | USD      | 15     |
 ---- ---------- -------- 
| 2  | EUR      | 0      |
 ---- ---------- -------- 
| 3  | USD      | 20     |
 ---- ---------- -------- 
| 3  | EUR      | 0      |
 ---- ---------- -------- 
  

Я написал следующее:

 SELECT E.ID, E.CURRENCY, SUM(E.AMOUNT) AS AMOUNT
FROM @EXPENSE AS E
GROUP BY E.ID, E.CURRENCY
  

Но это не дает мне недостающую валюту и нулевые суммы.

Может кто-нибудь, пожалуйста, помочь?

Комментарии:

1. Я думаю, что в вашем описании отсутствует то, что вы также хотите сохранить заполнители для типа валюты и суммы. Таким образом, всегда будут два типа валюты (USD, EUR), но они не всегда обязательно будут содержать сумму, и в этом случае вы хотите, чтобы по умолчанию она была равна 0. Это точно?

Ответ №1:

Вам нужно CROSS объединить разные идентификаторы и разные валюты, а затем LEFT объединить с таблицей для агрегирования:

 SELECT i.ID, c.CURRENCY,
       COALESCE(SUM(AMOUNT), 0) TOTAL
FROM (SELECT DISTINCT ID FROM @EXPENSE) i
CROSS JOIN (SELECT DISTINCT CURRENCY FROM @EXPENSE) c
LEFT JOIN @EXPENSE e ON e.ID = i.ID AND e.CURRENCY = c.CURRENCY
GROUP BY i.ID, c.CURRENCY
ORDER BY i.ID, c.CURRENCY
  

Посмотрите демонстрацию.
Результаты:

 > ID | CURRENCY |    TOTAL
> -: | :------- | -------:
>  1 | EUR      |    110
>  1 | USD      |    180
>  2 | EUR      |      0
>  2 | USD      |     15
>  3 | EUR      |      0
>  3 | USD      |     20