Выбор одного и того же столбца дважды с разными условиями

0

Мне трудно достичь моей цели в SQL. Проработанные часы, читающие аналогичный вопрос здесь и в других местах, но моя проблема кажется уникальной.

Моя база данных состоит из нескольких столбцов:

имя клиента || проект || тип || дата || стоимость || коррекция
Клиент1 Project1 TV 2018-1 100 нет
Client1 Project1 TV 2018-1 -50 да

Поэтому таблица требует объяснений. (Он также имеет идентификатор auto_inc для каждой строки.) Correction = no означает, что это исходное значение, созданное при прогнозировании финансов. "Да" означает, что это более поздняя коррекция цен.

Моя цель - посмотреть прогноз и фактический бок о бок. Поэтому для каждого месяца он должен суммировать коррекцию = нет значений (что довольно просто с

SELECT date, SUM(cost) FROM table WHERE correction='no' GROUP BY date)

и затем перечислите все фактические значения (это просто SUM без предложения WHERE).

Строки должны быть сопоставлены на основе клиента, проекта, типа и даты. Это кажется довольно простым, но, естественно, я получаю ошибки с одной строкой. Логически я не могу найти решение о том, как это сделать, и я скорее начинающий пользователь SQL.

Я хочу:

  • столбец с месяцами,
  • столбец с SUM (стоимость) WHERE correction = 'no',
  • и колонка со всеми издержками, конечно, все они дифференцированы по месяцам.

Буду признателен за ввод.

Теги:

2 ответа

2
Лучший ответ

Используйте условную агрегацию.

Комбинированная функция выполняет вычисление по набору значений и возвращает одно значение.

условная агрегация - это агрегация условного выражения, например сумма всех затрат, где correction = 'no'. Это делается с помощью конструкции CASE внутри функции агрегации (здесь SUM):

select 
  year(date), month(date),
  sum(case when correction = 'no' then cost end) as sum_no,
  sum(case when correction = 'yes' then cost end) as sum_yes,
  sum(cost) as sum_total
from mytable
group by year(date), month(date)
order by year(date), month(date;
0

В подобном случае мне нравится разбивать его с помощью общих табличных выражений (CTE). Это позволяет мне рассчитать прогнозируемую стоимость для каждого клиента/проекта/месяца и установить это отдельно в одном CTE, затем отдельно рассчитать фактические затраты в другом CTE, а затем запросить у каждого из этих результатов.

WITH projection AS (
    SELECT [client name], project, type, date, SUM(cost) cost FROM test WHERE correction='no' GROUP BY [client name], project, type, date
),
actual AS (
    SELECT [client name], project, type, date, SUM(cost) cost FROM test GROUP BY [client name], project, type, date
)
SELECT p."client name", p.project, p.type, p.date, p.cost AS "projected cost", a.cost AS "actual cost"
FROM projection p
JOIN actual a ON a."client name" = p."client name"
AND a.project = p.project 
AND a.type = p.type
AND a.date = p.date

Примечание. Для построения тестовой таблицы и значений я использовал следующее:

CREATE TABLE test ([client name] VARCHAR(100), project VARCHAR(100), type VARCHAR (100), date VARCHAR(100), cost INT, correction VARCHAR(100))

INSERT INTO test VALUES ('Client1', 'Project1', 'TV','2018-1', 100, 'no')
INSERT INTO test VALUES ('Client1', 'Project1', 'TV','2018-1', 200, 'no')
INSERT INTO test VALUES ('Client1', 'Project1', 'TV','2018-2', 300, 'no')
INSERT INTO test VALUES ('Client1', 'Project1', 'TV','2018-2', 400, 'no')

INSERT INTO test VALUES ('Client1', 'Project1', 'TV','2018-1', -50, 'yes')
INSERT INTO test VALUES ('Client1', 'Project1', 'TV','2018-2', -99, 'yes')
INSERT INTO test VALUES ('Client1', 'Project1', 'TV','2018-2', -75, 'yes')

INSERT INTO test VALUES ('Client1', 'Project2', 'TV','2018-1', 10, 'no')
INSERT INTO test VALUES ('Client1', 'Project2', 'TV','2018-1', 20, 'no')
INSERT INTO test VALUES ('Client1', 'Project2', 'TV','2018-2', 30, 'no')
INSERT INTO test VALUES ('Client1', 'Project2', 'TV','2018-2', 40, 'no')

INSERT INTO test VALUES ('Client1', 'Project2', 'TV','2018-1', -50, 'yes')
INSERT INTO test VALUES ('Client1', 'Project2', 'TV','2018-2', -99, 'yes')

И мои результаты:

"client name"   project   type   date     "projected cost"  "actual cost"
--------------- --------- ------ -------- ---------------- --------------
Client1         Project1  TV     2018-1                300            250
Client1         Project1  TV     2018-2                700            526
Client1         Project2  TV     2018-1                 30            -20
Client1         Project2  TV     2018-2                 70            -29

Ещё вопросы

Сообщество Overcoder
Наверх
Меню