СВЕРТКА не работает со столбцом, в котором выполняется математическая операция с двумя агрегированными значениями

#mysql #sql

Вопрос:

Поэтому у меня есть упрощенный код ниже:

 SELECT
(
    t1.name,
    t1.shortName,
    (
    SUM(
        CASE WHEN condition1 THEN t1.qty
            WHEN condition2 THEN t1.qty * t1.multiplier 
        END)
    -
    SUM(
        (SELECT (
            CASE WHEN condition1 THEN t2.qty
                WHEN condition2 THEN t2.qty * t2.multiplier 
            END) AS count
        FROM table t2))
    ) AS variance
FROM table t1
GROUP BY t1.name, t1.shortName WITH ROLLUP
 

В приведенном выше коде отклонение показывает правильную сумму в каждой строке, за исключением строк итога/промежуточного итога.
При поиске в Google выясняется, что С помощью СВЕРТКИ работает только с агрегированными столбцами, поэтому вышесказанное не работает, потому что значение дисперсии больше похоже на константу, так как СУММА находится внутри нее…

Поэтому я попытался переписать код в это:

 SELECT
(
    t1.name,
    t1.shortName,
    SUM(
    
        CASE WHEN condition1 THEN t1.qty
            WHEN condition2 THEN t1.qty * t1.multiplier 
        END
    -
    
        (SELECT (
            CASE WHEN condition1 THEN t2.qty
                WHEN condition2 THEN t2.qty * t2.multiplier 
            END) AS count
        FROM table t2)
     ) AS variance
FROM table t1
GROUP BY t1.name, t1.shortName WITH ROLLUP
 

И это не работает…. В основном я хочу агрегировать значения в таблицах 1 и 2, затем выполнить математическую операцию между ними, отобразить результат в столбце, а затем выполнить СВЕРТКУ…

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

1. t2 не определен в вашем запросе, поэтому он не будет работать.

Ответ №1:

Проблема на самом деле в CASE выражении, а не в арифметике. Одним из обходных путей является вычисление неагрегированных значений в подзапросе:

 SELECT t1.name, t1.shortName,
       SUM(t1_cond) - SUM(t2_cond) AS variance
FROM (SELECT t1.*,
             (CASE WHEN condition1 THEN t1.qty
                   WHEN condition2 THEN t1.qty * t1.multiplier 
              END) as t1_cond,
             (CASE WHEN condition1 THEN t2.qty
                   WHEN condition2 THEN t2.qty * t2.multiplier 
              END) as t2_cond2
      FROM t1
     ) t1
GROUP BY t1.name, t1.shortName WITH ROLLUP;
 

Вот скрипка db<>, иллюстрирующая, что этот метод действительно вычисляет дисперсию (хотя и по рабочему запросу).