Заполнение всего столбца тем же значением, которое возвращается из оператора CASE - PullRequest
0 голосов
/ 28 декабря 2018

Я пытаюсь заполнить столбец одинаковым значением результата из результирующего оператора CASE во всей группировке s_date / part_no.

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

SELECT
        s_date,
        part_no,
        i_group,
        s_level,
        p_category,
        qty_filled,
        qty_total,
        relief_amt,
        extreme_amt,
        curr_mth_note,
        CASE
            WHEN curr_mth_note IS NOT NULL
                 AND i_group = '1'
                 AND s_level = '80' THEN qty_filled
            ELSE NULL
        END AS g1s1_filled
        FROM
        (
            SELECT
                t1.s_date,
                t1.part_no,
                t1.i_group,
                t1.s_level,
                t1.p_category,
                t1.qty_filled,
                t1.qty_total,
                mv.relief_amt,
                mv.extreme_amt,
                mv.curr_mth_note,
            FROM
                multi_table mv,
                t_table t1
            WHERE
                t1.part_no = mv.part_no
                AND mv.part_no = 'xxxx'
                AND t1.s_date = mv.s_date
                AND t1.s_date = '201805'
            GROUP BY
                t1.s_date,
                t1.i_group,
                t1.s_level,
                t1.part_no,
                t1.p_category,
                t1.qty_filled,
                t1.qty_total,
                mv.relief_amt,
                mv.extreme_amt,
                mv.curr_mth_note,
            ORDER BY
                t1.s_date,
                t1.i_group,
                t1.s_level DESC
        )
ORDER BY
    s_date,
    part_no,
    i_group,
    DECODE(s_level, '80', 1, '100', 2, 'Late', 3)

Текущий вывод для вышеупомянутого выглядит следующим образом:

enter image description here

Я пытаюсь / надеюсь получить весь столбец g1s1_filled, чтобыпоказать ту же сумму 67, где i_group = '1' and s_level = '80' для всех доступных комбинаций даты / части.

Итак, для этого столбца, чтобы показать это:

G1S1_FILLED
67
67
67
67
67

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

Ответы [ 4 ]

0 голосов
/ 28 декабря 2018

Вы можете удалить выражение CASE и переместить весь запрос (за исключением условия ORDER BY) в CTE.Затем вы можете самостоятельно JOIN добавить его к каждой строке g1s1_filled.

Примечание: вы должны быть осторожны при определении условий самостоятельного соединения;Я предоставил предложение ниже, вам может понадобиться его уточнить.

Запрос:

WITH cte AS (
    SELECT
        s_date,
        part_no,
        i_group,
        s_level,
        p_category,
        qty_filled,
        qty_total,
        relief_amt,
        extreme_amt,
        curr_mth_note
        FROM
        (
            SELECT
                t1.s_date,
                t1.part_no,
                t1.i_group,
                t1.s_level,
                t1.p_category,
                t1.qty_filled,
                t1.qty_total,
                mv.relief_amt,
                mv.extreme_amt,
                mv.curr_mth_note,
            FROM
                multi_table mv,
                t_table t1
            WHERE
                t1.part_no = mv.part_no
                AND mv.part_no = 'xxxx'
                AND t1.s_date = mv.s_date
                AND t1.s_date = '201805'
            GROUP BY
                t1.s_date,
                t1.i_group,
                t1.s_level,
                t1.part_no,
                t1.p_category,
                t1.qty_filled,
                t1.qty_total,
                mv.relief_amt,
                mv.extreme_amt,
                mv.curr_mth_note,
            ORDER BY
                t1.s_date,
                t1.i_group,
                t1.s_level DESC
        )
)
SELECT a.*, b.qty_filled as g1s1_filled
FROM 
    cte AS a
    INNER JOIN cte as b 
        ON  b.s_date = a.s_date 
        AND b.part_no = a.part_no 
        AND b.i_group = '1' 
        AND b.s_level = '80'
        AND b.curr_mth_note IS NOT NULL
ORDER BY
    a.s_date,
    a.part_no,
    a.i_group,
    DECODE(a.s_level, '80', 1, '100', 2, 'Late', 3)
0 голосов
/ 28 декабря 2018

Вы можете использовать условный аналитический минимум в предложении SELECT.У меня нет ваших данных, поэтому я проиллюстрирую аналогичный запрос в таблице SCOTT.EMP - предположим, что я хочу заполнить NEWCOL зарплатой одного конкретного сотрудника.Я бы сделал это так:

select empno, ename, sal, job, deptno,
       min(case when empno = 7499 and ename = 'ALLEN' then sal end) over () as newcol
from   scott.emp;

     EMPNO ENAME             SAL JOB           DEPTNO     NEWCOL
---------- ---------- ---------- --------- ---------- ----------
      7369 SMITH             800 CLERK             20       1600
      7499 ALLEN            1600 SALESMAN          30       1600
      7521 WARD             1250 SALESMAN          30       1600
      7566 JONES            2975 MANAGER           20       1600
      7654 MARTIN           1250 SALESMAN          30       1600
      7698 BLAKE            2850 MANAGER           30       1600
      7782 CLARK            2450 MANAGER           10       1600
      7788 SCOTT            3000 ANALYST           20       1600
      7839 KING             5000 PRESIDENT         10       1600
      7844 TURNER           1500 SALESMAN          30       1600
      7876 ADAMS            1100 CLERK             20       1600
      7900 JAMES             950 CLERK             30       1600
      7902 FORD             3000 ANALYST           20       1600
      7934 MILLER           1300 CLERK             10       1600

Если (в вашей задаче) есть только одна строка со «специальной» комбинацией значений в I_GROUP и S_LEVEL, то вы можете использовать (условно(аналитические) MIN или MAX или даже AVG или SUM - все они будут равны одному значению, 67 в вашем случае.Если таких значений несколько, вам нужно будет сделать выбор: хотите ли вы MIN, MAX, AVG или что-то еще.В любом случае, вы все равно можете использовать ту же идею.

0 голосов
/ 28 декабря 2018

Я думаю, вы хотите функцию окна:

    SUM(CASE WHEN curr_mth_note IS NOT NULL AND i_group = '1' AND
                  s_level = '80'
             THEN qty_filled
        END) OVER (PARTITION BY s_date, part_no)  AS g1s1_filled
0 голосов
/ 28 декабря 2018

вместо оператора case, напишите для него подзапрос

(select qty_filled 
  from t_Table 
  where 
    i_group = '1' and 
    s_level = '80' and
    rownum = 1 
) as g1s1_filled
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...