#sql #postgresql #casting #case #aggregate-functions
#sql #postgresql #Кастинг #случай #агрегатные функции
Вопрос:
Я хочу перечислить положительные и отрицательные bank_transfers
значения из моей базы данных. Для этого я использую запрос ниже:
SELECT
bank_transfers.date AS day,
CAST(SUM(CASE WHEN bank_transfers.amount_cents < 0 THEN bank_transfers.amount_cents END)) AS sum_expenses,
CAST(SUM(CASE WHEN bank_transfers.amount_cents > 0 THEN bank_transfers.amount_cents END)) AS sum_revenue
FROM bank_transfers
JOIN customers ON customers.id = bank_transfers.customer_id
WHERE customers.id = 1
AND bank_transfers.date < '2020-11-26'
AND bank_transfers.date >= '2020-08-26'
GROUP BY DAY
Но это выдает ошибку syntax error at or near ")"
. Я предполагаю, что это происходит из CAST
so, где я должен закрыть круглые скобки?
Ответ №1:
Вам даже не нужны эти приведения. Вы не выполняете приведение ни к какому типу (если sum_expenses
только и sum_revenue
не являются вашими пользовательскими типами).
Редактировать: если вы хотите привести к целому числу:
SELECT
bank_transfers.date AS day,
SUM(CASE WHEN bank_transfers.amount_cents < 0 THEN bank_transfers.amount_cents END)::integer AS sum_expenses,
SUM(CASE WHEN bank_transfers.amount_cents > 0 THEN bank_transfers.amount_cents END)::integer AS sum_revenue
FROM bank_transfers
JOIN customers ON customers.id = bank_transfers.customer_id
WHERE customers.id = 1
AND bank_transfers.date < '2020-11-26'
AND bank_transfers.date >= '2020-08-26'
GROUP BY DAY
Или использовать cast(... as integer)
.
Комментарии:
1. Без
CAST
этого я получу число с плавающей запятой, например-4441.0
, вместо-4441
2. @mr_muscle добавьте
::integer
илиcast(... as integer)
. Я обновил свой ответ3. @mr_muscle нет,
CAST(SUM(CASE WHEN bank_transfers.amount_cents < 0 THEN bank_transfers.amount_cents END) as integer) AS sum_expenses
Ответ №2:
Вам даже не нужно a JOIN
для этого запроса, потому что клиент id
находится в bank_transfers
таблице. Я также настоятельно рекомендую FILTER
для условной агрегации:
SELECT bt.date AS day,
SUM(bt.amount_cents) FILTER (WHERE bt.amount_cents < 0) as sum_expenses,
SUM(bt.amount_cents) FILTER (WHERE bt.amount_cents > 0) as sum_revenue
FROM bank_transfers bt
WHERE bt.customer_id = 1 AND
bt.date >= '2020-08-26' AND
bt.date < '2020-11-26'
GROUP BY DAY;