Упрощение оператора выбора SQL в Oracle SQL Developer - PullRequest
0 голосов
/ 26 октября 2018

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я работаю с SQL-запросом, содержащим более 200 строк кода, и на данный момент в нескольких случаях я просто повторяю один и тот же подзапрос несколько раз в этом операторе выбора. , В приведенном ниже коде я использую два из операторов выбора - много «util_qty» и «pct_avail», в обоих из которых есть уравнения. Внутри оператора LOW_CNT _ &% SELECT я снова и снова использую оба предыдущих двух оператора SELECT (это только один пример в моем коде). Я хотел бы иметь возможность составить уравнение один раз и присвоить его переменной. Есть ли способ сделать это? Я пытался использовать предложение WITH, но для этого вам нужно использовать предложение FROM, мое предложение FROM массивное и выглядело бы так же уродливо, если бы я использовал предложение WITH (плюс вместо того, чтобы повторять оператор SELECT сейчас, я бы просто повторяя утверждение ОТ).

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

SELECT 
    all_nbr.total_qty,
    NVL (avail_nbr.avail_qty, 0) AS avail_qty,
    100 * TRUNC ( (NVL (avail_nbr.avail_qty, 0) / all_nbr.total_qty), 2) AS pct_avail,

    CASE
        WHEN ((NVL (avail_nbr.avail_qty, 0)) < 35) 
        THEN CASE
                WHEN ((100 * TRUNC ( (NVL (avail_nbr.avail_qty, 0) / all_nbr.total_qty), 2)) < 35)
                THEN (35 - (NVL (avail_nbr.avail_qty, 0)))
                ELSE 0
             END
        ELSE 0
    END AS "LOW_CNT_&%"
FROM
...

Любая помощь будет потрясающей !!

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Я пытался использовать предложение WITH, но для этого вам нужно использовать предложение FROM, мое предложение FROM является массивным и выглядело бы так же безобразно, если бы я использовал предложение WITH (плюс вместо повторения SELECTзаявление сейчас я бы просто повторил заявление ОТ).

Вам не нужно повторять предложение from.Вы перемещаете весь запрос, включая это предложение, в CTE;вы просто вытаскиваете биты, которые основаны на предыдущих вычислениях, в основной запрос, что позволяет избежать повторения кода.

Структура будет выглядеть примерно так:

WITH cte AS (
    SELECT 
        all_nbr.total_qty,
        NVL (avail_nbr.avail_qty, 0) AS avail_qty,
        100 * TRUNC ( (NVL (avail_nbr.avail_qty, 0) / all_nbr.total_qty), 2) AS pct_avail,
    FROM
    ...
)
SELECT
    cte.total_qty,
    cte.avail_qty,
    cte.pct_avail,
    CASE
        WHEN cte.avail_qty, 0 < 35 
        THEN CASE
                WHEN cte.total_qty < 35
                THEN 35 - cte.avail_qty
                ELSE 0
             END
        ELSE 0
    END AS "LOW_CNT_&%"
FROM
    cte;

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

Или вместо встроенного представления принципал такой же:

SELECT
    total_qty,
    avail_qty,
    pct_avail,
    CASE
        WHEN avail_qty < 35
        THEN CASE
                WHEN total_qty < 35
                THEN 35 - avail_qty
                ELSE 0
             END
        ELSE 0
    END AS "LOW_CNT_&%"
FROM
(
    SELECT 
        all_nbr.total_qty,
        NVL (avail_nbr.avail_qty, 0) AS avail_qty,
        100 * TRUNC ( (NVL (avail_nbr.avail_qty, 0) / all_nbr.total_qty), 2) AS pct_avail,
    FROM
    ...
);
0 голосов
/ 26 октября 2018

Если подзапрос точно такой же, вы можете предварительно вычислить его как выражение общей таблицы (CTE).Например:

with
cte1 as (
  select ... -- long, tedious, repetitive SELECT here
),
cte2 as (
  select ... -- you can reference/use cte1 here
)
select ...
  from cte1 -- you can use cte1 here, multiple times if you want
  join cte2 -- you can also reference/use cte2 here, also multiple times
  join ... -- all other joins

cte1 (можно использовать любое имя) - это предварительно вычисленное табличное выражение, которое можно использовать несколько раз.Вы также можете иметь несколько CTE, каждый с разными именами;также каждый CTE может ссылаться на предыдущие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...