sql — добавить столбец с суммой другого столбца для запроса

#sql #postgresql #sum

Вопрос:

у меня довольно сложный вложенный запрос, который структурирован следующим образом:

 select descr, sum(percentage) as perc from
( COMPLEX QUERY HERE)
as A group by descr  order by perc desc
 

результат этого запроса таков:

 descr                           perc
------------------------------------
bottom (1 * 18 cm²)             2.77
totalarea (1 * 70 cm²)          2.49
innerwalls (1 * 22 cm²)         2.37
bottom (2 * 12 cm²)             1.55
innerwalls (2 * 17 cm²)         1.51
risperror                       0.29
totalnumberdefects (1 * 30 cm²) 0.00
clipserror                      0.00
outerwalls (1 * 18 cm²)         0.00
outerwalls (2 * 16 cm²)         0.00
 

Теперь мне нужно будет добавить столбец, содержащий Sum() perc , поэтому в этом случае я ожидал бы этого в результате:

 descr                           perc        sum
------------------------------------------------
bottom (1 * 18 cm²)             2.77       10.98
totalarea (1 * 70 cm²)          2.49       10.98
innerwalls (1 * 22 cm²)         2.37       10.98
bottom (2 * 12 cm²)             1.55       10.98
innerwalls (2 * 17 cm²)         1.51       10.98
risperror                       0.29       10.98
totalnumberdefects (1 * 30 cm²) 0.00       10.98
clipserror                      0.00       10.98
outerwalls (1 * 18 cm²)         0.00       10.98
outerwalls (2 * 16 cm²)         0.00       10.98
 

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

Как это можно сделать?

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

1. Какую СУБД вы используете?

2. @jarlh Я использую dbeaver 7.3.4 в базе данных postre

3. Я не знаком с этой СУБД. Поддерживает ли он ANSI SQL? Если это так, я полагаю, вы могли бы использовать общее табличное выражение, чтобы изолировать сложный запрос и вывести из него как свои perc , так и total столбцы.

4. Вы можете прочитать о CTE здесь , или я мог бы написать пример ответа.

Ответ №1:

Вы можете использовать функцию окна СУММЫ для вашего результата:

 WITH myquery AS (
  select descr, sum(percentage) as perc from
  ( COMPLEX QUERY HERE)
  as A group by descr  order by perc desc
)
SELECT *, SUM(perc) OVER () AS "sum"
FROM myquery
 

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

1. (Комментарий к оригинальному постеру, @sharkyenergy) Это показывает использование CTE, аналогично тому, что я бы сделал.

2. Большое вам спасибо, никогда не слышал об утверждении «over». посмотрим на это!

Ответ №2:

Использовать sum() с функцией as window:

 SELECT *,SUM(perc) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM (your_complex_sql_query) j
 

Фрейм RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING в этом случае необязателен, поскольку фрейм не имеет порядка или раздела, но считается хорошей практикой делать вещи явными. Таким образом, вы также можете просто использовать OVER ()

 SELECT *,SUM(perc) OVER ()
FROM (your_complex_sql_query) j
 

ДЕМОНСТРАЦИЯ: db<>fiddle

Ответ №3:

Без использования group by:

Раньше я window function sum() получал общее perc и общее perc с помощью descr.

 SELECT DISTINCT descr,
       SUM(perc) OVER (PARTITION BY descr) AS perc,
       SUM(perc) OVER () AS "sum"
FROM (COMPLEX QUERY HERE) AS sq;       
 

Или с помощью CTE :

 WITH cte AS (COMPLEX QUERY HERE)

SELECT DISTINCT descr,
       SUM(perc) OVER (PARTITION BY descr) AS perc,
       SUM(perc) OVER () AS "sum"
FROM cte;
 

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

1. Почему вы используете DISTINCT ? SELECT descr, SUM(perc), SUM(SUM(perc)) OVER () FROM cte GROUP BY descr кажется, имеет гораздо больше смысла?

2. Да, это так, потому что я не группирую по, поэтому, если вы не используете DISTINCT , у вас не будет строки по описанию. Вы можете проверить это здесь

3. Я знаю, что это работает, это просто очень своеобразный шаблон; вы создаете повторяющиеся строки, а затем удаляете их, где агрегаты as не имеют таких накладных расходов.

4. Нет, я не создаю повторяющиеся строки, строки находятся в таблице (в complex_subquery). Таким образом, я избегаю использования дополнительного подзапроса.

5. @MatBailie проверьте принятый ответ, он использовал на один подзапрос больше, чем я, чтобы получить тот же результат. Это другой подход.