как использовать абсолютную функцию с процентом в oracle - PullRequest
0 голосов
/ 06 апреля 2020
WITH b1
     AS (  SELECT COUNT (DISTINCT Sales) AS cnt,
                  TO_CHAR (Date, 'YYYY-MON') AS Period
             FROM orders
            WHERE Date BETWEEN DATE '2020-02-01' AND DATE '2020-02-29'
         GROUP BY TO_CHAR (Date, 'YYYY-MON')
         UNION ALL
           SELECT COUNT (DISTINCT Sales) AS cnt,
                  TO_CHAR (Date, 'YYYY-MON') AS Period
             FROM orders
            WHERE Date BETWEEN DATE '2020-03-01' AND DATE '2020-03-31'
         GROUP BY TO_CHAR (Date, 'YYYY-MON'))
  SELECT cnt,
         Period,
         CASE
            WHEN ROUND (
                      ABS (cnt - LAG (cnt, 1, cnt) OVER (ORDER BY period DESC))
                    / cnt
                    * 100,
                    2) < 0
            THEN
                  ROUND (
                       (cnt - LAG (cnt, 1, cnt) OVER (ORDER BY period DESC))
                     / cnt
                     * 100,
                     2)
               || '%'
               || '  (Increase) '
            WHEN ROUND (
                      (cnt - LAG (cnt, 1, cnt) OVER (ORDER BY period DESC))
                    / cnt
                    * 100,
                    2) > 0
            THEN
                  ROUND (
                       (cnt - LAG (cnt, 1, cnt) OVER (ORDER BY period DESC))
                     / cnt
                     * 100,
                     2)
               || '%'
               || '  (Decrease) '
         END
            AS variances
    FROM b1
ORDER BY Period;

1 Ответ

0 голосов
/ 06 апреля 2020

Не конвертируйте даты в строки для их округления. Особенно, если вы собираетесь заказать по этой строке. Вы не хотите, чтобы '2020-Feb' предшествовал '2020-Jan' ...

Во-вторых, у вас есть ABS() в части 'WHEN' вашего CASE выражения, но вам нужно в части THEN ...

CASE WHEN ABS(x) < 0  -- This is what you have, which is NEVER true

В-третьих, вашему CTE не нужно объединять два набора данных вместе, вам просто нужно одно предложение WHERE ...

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

WITH
    b1 AS
(
        -- Using ROUND and avoiding UNION ALL

    SELECT COUNT(DISTINCT Sales) AS cnt,
           ROUND(Date, 'MONTH') AS Period
      FROM orders
     WHERE Date >= DATE '2020-02-01'
       AND Date <  DATE '2020-04-01'
  GROUP BY ROUND(Date, 'MONTH')
),
    b2 AS
(
    SELECT cnt,
           Period,
           cnt - LAG (cnt, 1, cnt) OVER (ORDER BY period DESC)  AS delta
      FROM b1
)
SELECT cnt,
       Period,
       ROUND(
          ABS(delta) * 100 / cnt,
          2
       )
          AS variances,
       CASE WHEN delta < 0 THEN 'increase'
                           ELSE 'decrease' END   AS variance_direction
  FROM b2
 ORDER BY Period;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...