首页 > 解决方案 > 子查询,不必重用代码

问题描述

我有一个相对简单的任务,由于我目前正在接近它的方式,它正在成为一个雷区,我想知道是否有一种更整洁/更清洁的方式而没有那么多可重复的代码。

以我正在执行以下选择的情况为例:

select a.col1, a.col2, a.col3, a.col4, a.col5 from a

但是a.col2andb.col3是选择本身的结果,即上面的代码变为:

select a.col1,
        a.col2 = (select something from somewhere where a.id = b.id),
        a.col3 = (select something_else from somewhere_else where a.id = c.id)
from a

然后最重要的是,是使用and的 语句col4的结果 ,并且是另一个 使用,和and 的 语句,然后突然你有一些非常混乱和非常重复的东西:CASEcol2col3col5CASEcol4col3col2

       select a.col1,
            a.col2 = (select something from somewhere where a.id = b.id),
            a.col3 = (select something_else from somewhere_else where a.id = c.id),
            a.col4 = (
                      case
                         when (select something from somewhere where a.id = b.id) = 'X' then 'Y'
                         else 'Z'
                      end
            ),
            a.col5 = [INSERT ALL OF COL4 CODE HERE] = 'Something' THEN
                     (
                      case
                         when (select something_else_again from somewhere_else where a.id = b.id) = 'X' then 'Y'
                         else 'Z'
                      end
                      )

这是我目前遇到的现实生活中的问题,出于问题目的,我已尝试在上面进行简化。我肯定有一种更整洁的方法吗?

标签: sql

解决方案


根据数据库,您可以执行以下任何操作。前两个实质上创建了一个新的“结果表”,您可以从中选择并重用先前计算的结果。最后一个选项是使用函数进行简单的常规编程。

此外,选项 1 和 2 都会让您有机会加入更多表,在许多情况下,这比您在 select 子句中执行的子选择更可取

选项 1:with条款

这适用于 PostgreSQL,不确定它是否适用于其他数据库:

with result1 as (
   select  [calculation] col1,
           [calculation] col2,
           *
   from    a
),
result2 as (
   select  [calculation] col3,
           *
   from    result1
)
select     [calculation] col4,
           *
from       result2

选项 2:子查询

应该适用于所有数据库。

select     [calculation] col4,
           *
from       (
           select  [calculation] col3,
                   *
           from    (
                   select  [calculation] col1,
                           [calculation] col2,
                           *
                   from    a
                   ) tt
           ) t 

选项 3:功能/程序

这在一定程度上取决于数据库实现,您必须阅读它。但取决于您是否想跨多个查询重用逻辑,这可能是一个不错的选择。不利的一面是,在函数中进行选择会带来隐藏成本。

它可能是这样的:

CREATE OR REPLACE FUNCTION calcualtion1(id integer) RETURNS boolean AS $$
BEGIN
   RETURN [do calculation here];
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION calcualtion2(id integer) RETURNS boolean AS $$
BEGIN
   RETURN [call calculation1 from here];
END;
$$ LANGUAGE plpgsql;

[...]

select  calculation1(id) col1,
        calculation2(id) col2,
        calculation3(id) col3,
        calculation4(id) col4,
from    a

不过,我想得越多,我很确定在您的情况下,这在速度方面会有很多缺点。但是在这里注意它,以防其他有类似问题的人出现在这有帮助的地方。


推荐阅读