Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Oracle SQL Developer中简化SQL Select语句_Sql_Oracle - Fatal编程技术网

在Oracle SQL Developer中简化SQL Select语句

在Oracle SQL Developer中简化SQL Select语句,sql,oracle,Sql,Oracle,我现在面临的问题是,我正在处理一个包含200多行代码的SQL查询,目前在多种情况下,我只是在这个select语句中多次重复相同的子查询。在下面的代码中,我使用了两个select语句a lot avail\u qty和pct\u avail,这两个语句中都有等式。在LOW_CNT_&%SELECT语句中,我反复使用前两个SELECT语句,这只是我代码中的一个示例。我希望能够做一次等式,并将其分配给一个变量。有没有办法做到这一点?我尝试过使用WITH子句,但为此需要使用FROM子句,我的FROM子句

我现在面临的问题是,我正在处理一个包含200多行代码的SQL查询,目前在多种情况下,我只是在这个select语句中多次重复相同的子查询。在下面的代码中,我使用了两个select语句a lot avail\u qty和pct\u avail,这两个语句中都有等式。在LOW_CNT_&%SELECT语句中,我反复使用前两个SELECT语句,这只是我代码中的一个示例。我希望能够做一次等式,并将其分配给一个变量。有没有办法做到这一点?我尝试过使用WITH子句,但为此需要使用FROM子句,我的FROM子句非常庞大,如果我使用WITH子句,而不是重复SELECT语句,那么我的FROM子句看起来也一样难看。现在,我只是重复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,

    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
...

任何帮助都会很棒

如果子查询完全相同,则可以将其作为公共表表达式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具有不同的名称;此外,每个CTE可以参考以前的CTE

我尝试过使用WITH子句,但为此需要使用FROM子句,我的FROM子句非常庞大,如果我使用WITH子句,而不是重复SELECT语句,那么我的FROM子句看起来也一样难看。现在,我只是重复FROM语句

你不需要重复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
    ...
);

如果没有from子句,方程本身就没有多大意义。可以使用替换变量替换后面的代码位,但这并不十分直观。但我不确定我是否完全理解你在重复哪些片段,在哪里,为什么。从您刚才展示的内容来看,CTE或内联视图看起来是显而易见的解决方案,但不清楚为什么它不适合您。为什么您需要重复从-可能您没有正确使用CTE?您不能使用CTE吗?您可以有多个CTE,每个CTE都引用以前的CTE。你能详细说明CTE的问题吗?也许你想要的是一个可重用的功能?您可以使用with函数f as将这些声明为查询的一部分。。。从Oracle 12.1开始。